Rot-13: Difference between revisions

From Rosetta Code
Content deleted Content added
Rahul (talk | contribs)
added ruby, php
Line 6:
 
=={{header|Ada}}==
<ada>with Ada.Text_IO.Text_Streams; use Ada.Text_IO.Text_Streams;
with Ada.Strings.Maps; use Ada.Strings.Maps;
with Ada.Command_Line; use Ada.Command_Line;
 
procedure Rot_13 is
with Ada.Text_IO.Text_Streams; use Ada.Text_IO.Text_Streams;
with Ada.Strings.Maps; use Ada.Strings.Maps;
From_Sequence : Character_Sequence := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
with Ada.Command_Line; use Ada.Command_Line;
Result_Sequence : Character_Sequence := "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM";
Rot_13_Mapping : Character_Mapping := To_Mapping(From_Sequence, Result_Sequence);
 
In_Char : Character;
Stdio : Stream_Access := Stream(Ada.Text_IO.Standard_Input);
Stdout : Stream_Access := Stream(Ada.Text_Io.Standard_Output);
Input : Ada.Text_Io.File_Type;
begin
procedure Rot_13 is
if Argument_Count > 0 then
for I in 1..Argument_Count loop
From_Sequence : Character_Sequence := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
begin
Result_Sequence : Character_Sequence := "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM";
Ada.Text_Io.Open(File => Input, Mode => Ada.Text_Io.In_File, Name => Argument(I));
Rot_13_Mapping : Character_Mapping := To_Mapping(From_Sequence, Result_Sequence);
Stdio := Stream(Input);
while not Ada.Text_Io.End_Of_File(Input) loop
In_Char : Character;
In_Char :=Character'Input(Stdio);
Stdio : Stream_Access := Stream(Ada.Text_IO.Standard_Input);
Character'Output(Stdout, Value(Rot_13_Mapping, In_Char));
Stdout : Stream_Access := Stream(Ada.Text_Io.Standard_Output);
Input : Ada.Text_Io.File_Type end loop;
Ada.Text_IO.Close(Input);
exception
begin
when Ada.Text_IO.Name_Error =>
if Argument_Count > 0 then
Ada.Text_Io.Put_Line(File => Ada.Text_Io.Standard_Error, Item => "File " & Argument(I) & " is not a file.");
for I in 1..Argument_Count loop
begin when Ada.Text_Io.Status_Error =>
Ada.Text_Io.OpenPut_Line(File => Input, Mode => Ada.Text_Io.In_FileStandard_Error, NameItem => "File " & Argument(I) & " is already opened.");
Stdio := Stream(Input)end;
end loop;
while not Ada.Text_Io.End_Of_File(Input) loop
else
In_Char :=Character'Input(Stdio);
while not Ada.Text_Io.End_Of_File loop
Character'Output(Stdout, Value(Rot_13_Mapping, In_Char));
In_Char :=Character'Input(Stdio); end loop;
Character'Output(Stdout, Value(Rot_13_Mapping, In_Char));
Ada.Text_IO.Close(Input);
end exceptionloop;
end if;
when Ada.Text_IO.Name_Error =>
end Rot_13;</ada>
Ada.Text_Io.Put_Line(File => Ada.Text_Io.Standard_Error, Item => "File " & Argument(I) & " is not a file.");
when Ada.Text_Io.Status_Error =>
Ada.Text_Io.Put_Line(File => Ada.Text_Io.Standard_Error, Item => "File " & Argument(I) & " is already opened.");
end;
end loop;
else
while not Ada.Text_Io.End_Of_File loop
In_Char :=Character'Input(Stdio);
Character'Output(Stdout, Value(Rot_13_Mapping, In_Char));
end loop;
end if;
end Rot_13;
 
=={{header|BASIC}}==
Line 78 ⟶ 77:
=={{header|C}}==
 
<c>#include<stdio.h>
<pre>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
Line 123 ⟶ 121:
 
return EXIT_SUCCESS;
}</c>
}
</pre>
 
=={{header|C++}}==
<cpp>
#include <iostream>
#include <istream>
#include <ostream>
#include <fstream>
#include <cstdlib>
#include <string>
 
// the rot13 function
#include <iostream>
std::string rot13(std::string s)
#include <istream>
{
#include <ostream>
static std::string const
#include <fstream>
lcalph = "abcdefghijklmnopqrstuvwxyz",
#include <cstdlib>
ucalph = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
#include <string>
 
std::string result;
// the rot13 function
std::string rot13(std::stringsize_type s)pos;
 
{
result.reserve(s.length());
static std::string const
 
lcalph = "abcdefghijklmnopqrstuvwxyz",
for (std::string::iterator it = s.begin(); it != s.end(); ++it)
ucalph = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
{
if ( (pos = lcalph.find(*it)) != std::string::npos result;)
result.push_back(lcalph[(pos+13) % 26]);
std::string::size_type pos;
else if ( (pos = ucalph.find(*it)) != std::string::npos )
result.reservepush_back(s.lengthucalph[(pos+13) % 26]);
else
result.push_back(*it);
for (std::string::iterator it = s.begin(); it != s.end(); ++it)
{}
 
if ( (pos = lcalph.find(*it)) != std::string::npos )
return result.push_back(lcalph[(pos+13) % 26]);
}
else if ( (pos = ucalph.find(*it)) != std::string::npos )
 
result.push_back(ucalph[(pos+13) % 26]);
// function to output the rot13 of a file on std::cout
else
// returns false if an error occurred processing the file, true otherwise
result.push_back(*it);
// on entry, the argument is must be open for reading
}
int rot13_stream(std::istream& is)
{
return result;
std::string line;
}
while (std::getline(is, line))
{
// function to output the rot13 of a file on std::cout
if (!(std::cout << rot13(line) << "\n"))
// returns false if an error occurred processing the file, true otherwise
return false;
// on entry, the argument is must be open for reading
}
int rot13_stream(std::istream& is)
return is.eof();
{
}
std::string line;
 
while (std::getline(is, line))
// the main program
{
int main(int argc, char* argv[])
if (!(std::cout << rot13(line) << "\n"))
{
return false;
if (argc == 1) // no arguments given
}
return is.eofrot13_stream(std::cin)? EXIT_SUCCESS : EXIT_FAILURE;
 
}
std::ifstream file;
for (int i = 1; i < argc; ++i)
// the main program
{
int main(int argc, char* argv[])
file.open(argv[i], std::ios::in);
{
if (!file)
if (argc == 1) // no arguments given
{
return rot13_stream(std::cin)? EXIT_SUCCESS : EXIT_FAILURE;
std::cerr << argv[0] << ": could not open for reading: " << argv[i] << "\n";
return EXIT_FAILURE;
std::ifstream file;
}
for (int i = 1; i < argc; ++i)
if (!rot13_stream(file))
{
{
file.open(argv[i], std::ios::in);
if (!file.eof())
// no error occurred for file, so the error must have been in output
{
std::cerr << argv[0] << ": coulderror notwriting opento for reading: " << argv[i] << "stdout\n";
return EXIT_FAILURE;else
std::cerr << argv[0] << ": error reading from " << argv[i] << "\n";
}
if (!rot13_stream(file))return EXIT_FAILURE;
{}
if (file.eofclear());
file.close();
// no error occurred for file, so the error must have been in output
if (!file)
std::cerr << argv[0] << ": error writing to stdout\n";
std::cerr << argv[0] << ": warning: closing failed for " << argv[i] << "\n";
else
}
std::cerr << argv[0] << ": error reading from " << argv[i] << "\n";
return EXIT_FAILUREEXIT_SUCCESS;
}</cpp>
}
file.clear();
file.close();
if (!file)
std::cerr << argv[0] << ": warning: closing failed for " << argv[i] << "\n";
}
return EXIT_SUCCESS;
}
 
=={{header|D}}==
Line 245 ⟶ 242:
A simpler version (D V.1):
 
<d>import std.stdio, std.string;
<d>
import std.stdio, std.string;
void main() {
auto r13 = letters.maketrans(uppercase[13..$] ~ uppercase[0..13] ~
lowercase[13..$] ~ lowercase[0..13]);
writefln("This is the 1st test!".translate(r13, null));
}</d>
}
</d>
 
=={{header|Forth}}==
Line 338 ⟶ 333:
rot13 :: Char -> Char
rot13 c
| c < >= 'A' && c <= 'M' = chr (ord c + 13)
| c < >= 'Na' && c <= 'm' = chr (ord c + 13)
| c >= 'N' && c <= 'Z' = chr (ord c - 13)
| c < >= 'an' && c <= 'z' = chr (ord c - 13)
| c < 'n' = chr (ord c + 13)
| c <= 'z' = chr (ord c - 13)
| otherwise = c
Line 403 ⟶ 396:
 
=={{header|Java}}==
<java>
import java.io.BufferedReader;
import java.io.FileNotFoundExceptionBufferedReader;
import java.io.FileReaderFileNotFoundException;
import java.io.IOExceptionFileReader;
import java.io.InputStreamReaderIOException;
import java.io.InputStreamReader;
public class ROT13{
public class ROT13{
public static void main(String[] args){
public static void main(String[] args){
BufferedReader in;
BufferedReader if(args.length >= 1){in;
forif(Stringargs.length file:>= args1){
for(String file: tryargs){
in= new BufferedReader(new FileReader(file));try{
in= Stringnew lineBufferedReader(new FileReader(file));
String while((line= in.readLine()) != null){;
while((line= Systemin.out.printlnreadLine(convert(line)); != null){
} System.out.println(convert(line));
}catch(FileNotFoundException e){ }
}catch(FileNotFoundException e.printStackTrace();{
}catch(IOException e.printStackTrace(){;
}catch(IOException e.printStackTrace();{
} e.printStackTrace();
}
}else{
try}else{
in= new BufferedReader(new InputStreamReader(System.in));try{
in= Stringnew lineBufferedReader(new InputStreamReader(System.in));
String while((line= in.readLine()) != null){;
while((line= Systemin.out.printlnreadLine(convert(line)); != null){
} System.out.println(convert(line));
}catch(IOException e){ }
}catch(IOException e.printStackTrace();{
} e.printStackTrace();
}
}
}
public static String convert(String msg){
public static String convert(String retVal= "";msg){
String for(charretVal= a: msg.toCharArray()){"";
iffor(a >= 'A' &&char a: <= 'Z'msg.toCharArray()){
if(a >= 'A' && a a+<= 13;'Z'){
if(a > 'Z') a-+= 2613;
}else if(a >= 'aZ' &&) a <-= 'z'){26;
}else if(a >= 'a' && a+ <= 13;'z'){
if(a > 'z') a-+= 2613;
} if(a > 'z') a-= 26;
retVal+= a;}
} retVal+= a;
return retVal;}
} return retVal;
}
}
}</java>
 
=={{header|JavaScript}}==
<javascript>var rot13Str = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM";
var plainStr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
function rot13(s) {
var a = [];
for (var i=0; i<s.length; i++) {
var c = s.charAt(i);
var found = plainStr.indexOf(c);
a.push(found<0 ? c : rot13Str.charAt(found));
}
return a.join(<nowiki>''</nowiki>);
}
 
alert( rot13("ABJURER nowhere") ); // NOWHERE abjurer</javascript>
 
=={{header|OCaml}}==
Line 488 ⟶ 482:
 
=={{header|Perl}}==
<perl>sub rot13 {
$string = shift;
$string =~ tr/[A-Z][a-z]/[N-ZA-M][n-za-m]/;
return $string;
}
 
$alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
print rot13($alpha), "\n";</perl>
 
Output:
NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm
 
=={{header|PHP}}==
 
PHP has a built-in function for this:
<php>echo str_rot13('foo'), "\n";</php>
will output
sbb
 
Here is an implementation:
<php><?php
function rot13($s) {
return strtr($s, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm');
}
 
echo rot13('foo'), "\n";
?></php>
 
Output:
sbb
 
=={{header|Pop11}}==
Line 533 ⟶ 547:
 
Here is an implementation:
<python>#!/usr/bin/env python
import string
def rot13(s):
"""Implement the rot-13 encoding function: "rotate" each letter by the
letter that's 13 steps from it (wrapping from z to a)
"""
return string.translate( s,
string.maketrans(
string.uppercase + string.lowercase,
string.uppercase[13:] + string.uppercase[:13] +
string.lowercase[13:] + string.lowercase[:13]
)
)
if __name__ == "__main__":
"""Peform line-by-line rot-13 encoding on any files listed on our
command line or act as a standard UNIX filter (if no arguments
specified).
"""
import fileinput
for line in fileinput.input():
print rot13(line), # (Note the trailing comma; avoid double-spacing our output)!</python>
 
The ''string.translate()'' and ''string.maketrans()'' functions make the function's definition almost trivial. It's a one-line function with some line wrapping for legibility. The ''fileinput'' module similarly makes the wrapper functionality trivial to implement. (This implementation is about seven logical lines long).
 
=={{header|Ruby}}==
<ruby>def rot13(s)
s.tr('A-Za-z', 'N-ZA-Mn-za-m')
end
 
alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
puts rot13(alpha)</ruby>
 
Output:
NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm
 
=={{header|Seed7}}==

Revision as of 10:03, 19 December 2008

Task
Rot-13
You are encouraged to solve this task according to the task description, using any language you may know.

Implement a "rot-13" function (or procedure, class, subroutine, or other "callable" object as appropriate to your programming environment). Optionally wrap this function in a utility program which acts like a common UNIX utility, performing a line-by-line rot-13 encoding of every line of input contained in each file listed on its command line, or (if no filenames are passed thereon) acting as a filter on its "standard input." (A number of UNIX scripting languages and utilities, such as awk and sed either default to processing files in this way or have command line switches or modules to easily implement these wrapper semantics, i.e. Perl and Python).

The "rot-13" encoding is commonly known from the early days of Usenet "Netnews" as a way of obfuscating text to prevent casual reading of spoilers or other potentially offensive material. Many news reader and mail user agent programs have built-in "rot-13" encoder/decoders or have the ability to feed a message through any external utility script for performing this (or other) actions.

The definition of the rot-13 function is to simply replace every letter of the ASCII alphabet with the letter which is "rotated" 13 characters "around" the 26 letter alphabet from it's normal cardinal position (wrapping around from "z" to "a" as necessary). Thus the letters "abc" become "nop" and so on. Technically rot-13 is a "monoalphabetic substitution cipher" will a trivial "key". A proper implementation should work on upper and lower case letters, preserve case, and pass all non-alphabetic characters in the input stream through without alteration.

Ada

<ada>with Ada.Text_IO.Text_Streams; use Ada.Text_IO.Text_Streams; with Ada.Strings.Maps; use Ada.Strings.Maps; with Ada.Command_Line; use Ada.Command_Line;

procedure Rot_13 is

  From_Sequence : Character_Sequence := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  Result_Sequence : Character_Sequence := "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM";
  Rot_13_Mapping : Character_Mapping := To_Mapping(From_Sequence, Result_Sequence);
  In_Char : Character;
  Stdio : Stream_Access := Stream(Ada.Text_IO.Standard_Input);
  Stdout : Stream_Access := Stream(Ada.Text_Io.Standard_Output);
  Input : Ada.Text_Io.File_Type;

begin

  if Argument_Count > 0 then
     for I in 1..Argument_Count loop
        begin
           Ada.Text_Io.Open(File => Input, Mode => Ada.Text_Io.In_File, Name => Argument(I));
           Stdio := Stream(Input);
            while not Ada.Text_Io.End_Of_File(Input) loop
              In_Char :=Character'Input(Stdio); 
              Character'Output(Stdout, Value(Rot_13_Mapping, In_Char));
           end loop;
           Ada.Text_IO.Close(Input);
        exception
           when Ada.Text_IO.Name_Error =>
              Ada.Text_Io.Put_Line(File => Ada.Text_Io.Standard_Error, Item => "File " & Argument(I) & " is not a file.");
           when Ada.Text_Io.Status_Error =>
              Ada.Text_Io.Put_Line(File => Ada.Text_Io.Standard_Error, Item => "File " & Argument(I) & " is already opened.");
        end;
     end loop;
  else
     while not Ada.Text_Io.End_Of_File loop
        In_Char :=Character'Input(Stdio); 
        Character'Output(Stdout, Value(Rot_13_Mapping, In_Char));
     end loop;
  end if;

end Rot_13;</ada>

BASIC

Works with: QuickBasic version 4.5
CLS
INPUT "Enter a string: ", s$
ans$ = ""
FOR a = 1 TO LEN(s$)
        letter$ = MID$(s$, a, 1)
        char$ = ""
        IF letter$ >= "A" AND letter$ <= "Z" THEN
                char$ = CHR$(ASC(letter$) + 13)
                IF char$ > "Z" THEN char$ = CHR$(ASC(char$) - 26)
        ELSEIF letter$ >= "a" AND letter$ <= "z" THEN
                char$ = CHR$(ASC(letter$) + 13)
                IF char$ > "z" THEN char$ = CHR$(ASC(char$) - 26)
        ELSE
                char$ = letter$
        END IF
        ans$ = ans$ + char$
NEXT a
PRINT ans$

Befunge

~:"z"`#v_:"m"`#v_:"`"` |>
 :"Z"`#v_:"M"`#v_:"@"`|>
 : 0 `#v_@v-6-7<      >
,      <  <+6+7       <<v

C

<c>#include<stdio.h>

  1. include<stdlib.h>
  2. include<ctype.h>
  1. define MAXLINE 1024

char *rot13(char *s) {

       char *p=s;
       int upper;
       while(*p) {
               upper=toupper(*p);
               if(upper>='A' && upper<='M') *p+=13;
               else if(upper>='N' && upper<='Z') *p-=13;
               ++p;
       }
       }
       return s;

}

void rot13file(FILE *fp) {

       static char line[MAXLINE];
       while(fgets(line, MAXLINE, fp)>0) fputs(rot13(line), stdout);

}

int main(int argc, char *argv[]) {

       int n;
       FILE *fp;
       if(argc>1) {
               for(n=1; n<argc; ++n) {
                       if(!(fp=fopen(argv[n], "r"))) {
                               fprintf(stderr, "ERROR: Couldn\'t read %s\n", argv[n]);
                               exit(EXIT_FAILURE);
                       }
                       rot13file(fp);
                       fclose(fp);
               }
       } else rot13file(stdin);
       return EXIT_SUCCESS;

}</c>

C++

<cpp>

  1. include <iostream>
  2. include <istream>
  3. include <ostream>
  4. include <fstream>
  5. include <cstdlib>
  6. include <string>

// the rot13 function std::string rot13(std::string s) {

 static std::string const
   lcalph = "abcdefghijklmnopqrstuvwxyz",
   ucalph = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 std::string result;
 std::string::size_type pos;
 result.reserve(s.length());
 for (std::string::iterator it = s.begin(); it != s.end(); ++it)
 {
   if ( (pos = lcalph.find(*it)) != std::string::npos )
     result.push_back(lcalph[(pos+13) % 26]);
   else if ( (pos = ucalph.find(*it)) != std::string::npos )
     result.push_back(ucalph[(pos+13) % 26]);
   else
     result.push_back(*it);
 }
 return result;

}

// function to output the rot13 of a file on std::cout // returns false if an error occurred processing the file, true otherwise // on entry, the argument is must be open for reading int rot13_stream(std::istream& is) {

 std::string line;
 while (std::getline(is, line))
 {
   if (!(std::cout << rot13(line) << "\n"))
     return false;
 }
 return is.eof();

}

// the main program int main(int argc, char* argv[]) {

 if (argc == 1) // no arguments given
   return rot13_stream(std::cin)? EXIT_SUCCESS : EXIT_FAILURE;
 std::ifstream file;
 for (int i = 1; i < argc; ++i)
 {
   file.open(argv[i], std::ios::in);
   if (!file)
   {
     std::cerr << argv[0] << ": could not open for reading: " << argv[i] << "\n";
     return EXIT_FAILURE;
   }
   if (!rot13_stream(file))
   {
     if (file.eof())
       // no error occurred for file, so the error must have been in output
       std::cerr << argv[0] << ": error writing to stdout\n";
     else
       std::cerr << argv[0] << ": error reading from " << argv[i] << "\n";
     return EXIT_FAILURE;
   }
   file.clear();
   file.close();
   if (!file)
     std::cerr << argv[0] << ": warning: closing failed for " << argv[i] << "\n";
 }
 return EXIT_SUCCESS;

}</cpp>

D

Implement a Rot-13 function. <d>module rot13 ; import std.stdio ;

version(D_Version2) {

 import std.algorithm ;

}

char rot13char(char t) {

 ubyte c = (t & 0x9f) - 1 ;
 if (c > 25 || (t & 0x40) == 0 )
   return t ;
 c = (c + 13) % 26 ; // that's why Rot-13 :)
 return (t & 0x60) | (c + 1) ;   

}

string rot13(string s) {

 string t ;
 foreach(c ; s)
   t ~= rot13char(c) ;
 return t ;

}

void main(string[] args) {

 string text = "abc! ABC!" ;
 writefln(rot13(text)) ;
 writefln(rot13("abcdefghijklmnopqrstuvwxyz"~
                "ABCDEFGHIJKLMNOPQRSTUVWXYZ")) ;

version(D_Version2) {

 writefln(map!(rot13char)(text)) ; 
 writefln(map!(rot13char)("abcdefghijklmnopqrstuvwxyz"~ 
                          "ABCDEFGHIJKLMNOPQRSTUVWXYZ")) ;

} }</d>

A simpler version (D V.1):

<d>import std.stdio, std.string; void main() {

   auto r13 = letters.maketrans(uppercase[13..$] ~ uppercase[0..13] ~
                                lowercase[13..$] ~ lowercase[0..13]);
   writefln("This is the 1st test!".translate(r13, null));

}</d>

Forth

A simple version, using nested conditionals.

: r13 ( c -- o )
  dup 32 or                                    \ tolower
  dup [char] a [char] z 1+ within if
    [char] m > if -13 else 13 then +
  else drop then ;

A table driven version which should be more efficient. The mechanism is flexible enough to express any sort of transform.

: ,chars ( end start -- )
  do i c, loop ;

: xlate create does> ( c -- c' ) + c@ ;

xlate rot13 
  char A         0    ,chars
  char Z 1+ char N    ,chars
  char N    char A    ,chars
  char a    char Z 1+ ,chars
  char z 1+ char n    ,chars
  char n    char a    ,chars
  256       char z 1+ ,chars

: rot13-string ( addr len -- )
  over + swap do i c@ rot13 i c! loop ;

: .rot13" ( string -- )
  [char] " parse 2dup rot13-string type ;
 
.rot13" abjurer NOWHERE"   \ nowhere ABJURER

Fortran

Works with: Fortran version 90 and later
MODULE ROT13
  IMPLICIT NONE
  CHARACTER(80) :: teststr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ - abcdefghijklmnopqrstuvwxyz"

  CONTAINS

  SUBROUTINE ROT_13(s)
    CHARACTER(*), INTENT(in out) :: s
    INTEGER :: i

    DO i = 1, LEN(s)
       SELECT CASE (s(i:i))
         CASE ("A":"M")
           s(i:i) = ACHAR(IACHAR(s(i:i))+13)
         
         CASE ("N":"Z")
           s(i:i) = ACHAR(IACHAR(s(i:i))-13)
         
         CASE ("a":"m")
           s(i:i) = ACHAR(IACHAR(s(i:i))+13)
         
         CASE ("n":"z")
           s(i:i) = ACHAR(IACHAR(s(i:i))-13)
       END SELECT
    END DO
  END SUBROUTINE ROT_13
END MODULE ROT13

PROGRAM Example
  USE ROT13
 
  CALL ROT_13(teststr)
  WRITE(*,*) teststr
  CALL ROT_13(teststr)
  WRITE(*,*) teststr

END PROGRAM Example

Ouput

NOPQRSTUVWXYZABCDEFGHIJKLM - nopqrstuvwxyzabcdefghijklm
ABCDEFGHIJKLMNOPQRSTUVWXYZ - abcdefghijklmnopqrstuvwxyz

Haskell

Straightforward implementation by checking multiple cases:

import Data.Char

rot13 :: Char -> Char
rot13 c
  | c >= 'A' && c <= 'M' = chr (ord c + 13)
  | c >= 'a' && c <= 'm' = chr (ord c + 13)
  | c >= 'N' && c <= 'Z' = chr (ord c - 13)
  | c >= 'n' && c <= 'z' = chr (ord c - 13)
  | otherwise = c

To wrap that as an utility program, here's a quick implementation of a general framework:

import System.Environment
import System.IO
import System.Directory
import Control.Monad

hInteract :: (String -> String) -> Handle -> Handle -> IO ()
hInteract f hIn hOut =
  hGetContents hIn >>= hPutStr hOut . f

processByTemp :: (Handle -> Handle -> IO ()) -> String -> IO ()
processByTemp f name = do
  hIn <- openFile name ReadMode
  let tmp = name ++ "$" 
  hOut <- openFile tmp WriteMode
  f hIn hOut
  hClose hIn
  hClose hOut
  removeFile name
  renameFile tmp name

process :: (Handle -> Handle -> IO ()) -> [String] -> IO ()
process f [] = f stdin stdout
process f ns = mapM_ (processByTemp f) ns

Then the wrapped program is simply

main = do
  names <- getArgs
  process (hInteract (map rot13)) names

Note that the framework will read the file lazily, which also provides buffering.

Icon

like javascript

procedure main()
   local str, plain, rot13
   rot13 := "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM";
   plain := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
   str := "ABJURER nowhere"
   write(map(str, plain, rot13))
end

J

rot13=: (a.,~a.{~,65 97+/26|13+i.26) {~ (a.,~a.{~,65 97+/i.26) i. ]

For example:

   rot13 'abc! ABC!'
nop! NOP!

Compare with the solution to the Change String Case task.

Java

<java> import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; public class ROT13{

      public static void main(String[] args){
              BufferedReader in;
              if(args.length >= 1){
                      for(String file: args){
                              try{
                                      in= new BufferedReader(new FileReader(file));
                                      String line;
                                      while((line= in.readLine()) != null){
                                              System.out.println(convert(line));
                                      }
                              }catch(FileNotFoundException e){
                                      e.printStackTrace();
                              }catch(IOException e){
                                      e.printStackTrace();
                              }
                      }
              }else{
                      try{
                              in= new BufferedReader(new InputStreamReader(System.in));
                              String line;
                              while((line= in.readLine()) != null){
                                      System.out.println(convert(line));
                              }
                      }catch(IOException e){
                              e.printStackTrace();
                      }
              }
      }
      public static String convert(String msg){
              String retVal= "";
              for(char a: msg.toCharArray()){
                      if(a >= 'A' && a <= 'Z'){
                              a+= 13;
                              if(a > 'Z') a-= 26;
                      }else if(a >= 'a' && a <= 'z'){
                              a+= 13;
                              if(a > 'z') a-= 26;
                      }
                      retVal+= a;
              }
              return retVal;
      }

}</java>

JavaScript

<javascript>var rot13Str = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM"; var plainStr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

function rot13(s) {

 var a = [];
 for (var i=0; i<s.length; i++) {
   var c = s.charAt(i);
   var found = plainStr.indexOf(c);
   a.push(found<0 ? c : rot13Str.charAt(found));
 }
 return a.join('');

}

alert( rot13("ABJURER nowhere") ); // NOWHERE abjurer</javascript>

OCaml

Straightforward implementation for characters by using character range patterns: <ocaml>let rot13 c = match c with

  'A'..'M'
| 'a'..'m' -> char_of_int (int_of_char c + 13)
| 'N'..'Z'
| 'n'..'z' -> char_of_int (int_of_char c - 13)
| _        -> c</ocaml>

We provide a function for converting whole strings: <ocaml>let rot13_str s =

 let len = String.length s in
 let result = String.create len in
 for i = 0 to len - 1 do
   result.[i] <- rot13 s.[i]
 done;
 result</ocaml>

Perl

<perl>sub rot13 {

 $string = shift;
 $string =~ tr/[A-Z][a-z]/[N-ZA-M][n-za-m]/;
 return $string;

}

$alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; print rot13($alpha), "\n";</perl>

Output:

NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm

PHP

PHP has a built-in function for this: <php>echo str_rot13('foo'), "\n";</php> will output

sbb

Here is an implementation: <php><?php function rot13($s) {

   return strtr($s, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
                    'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm');

}

echo rot13('foo'), "\n"; ?></php>

Output:

sbb

Pop11

In Pop11 characters are just integers, so we can use integer comparisons and arithmetic (assuming ASCII based encoding).

define rot13(s);
    lvars j, c;
    for j from 1 to length(s) do
        s(j) -> c;
        if `A` <= c and c <= `M` or `a` <= c and c <= `m` then
            c + 13 -> s(j);
        elseif `N` <= c and c <= `Z` or `n` <= c and c <= `z` then
            c - 13 -> s(j);
        endif;
    endfor;
    s;
enddefine;

rot13('NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm') =>

Python

Python has built-in rot13 encoding and decoding:

>>> u'foo'.encode('rot13')
'sbb'
>>> 'sbb'.decode('rot13')
u'foo'

Here is an implementation: <python>#!/usr/bin/env python import string def rot13(s):

  """Implement the rot-13 encoding function: "rotate" each letter by the
     letter that's 13 steps from it (wrapping from z to a)
  """
  return string.translate( s,
      string.maketrans(
          string.uppercase + string.lowercase,
          string.uppercase[13:] + string.uppercase[:13] +
          string.lowercase[13:] + string.lowercase[:13]
          )
      )

if __name__ == "__main__":

  """Peform line-by-line rot-13 encoding on any files listed on our
     command line or act as a standard UNIX filter (if no arguments
     specified).
  """
  import fileinput
  for line in fileinput.input():
     print rot13(line),  # (Note the trailing comma; avoid double-spacing our output)!</python>

The string.translate() and string.maketrans() functions make the function's definition almost trivial. It's a one-line function with some line wrapping for legibility. The fileinput module similarly makes the wrapper functionality trivial to implement. (This implementation is about seven logical lines long).

Ruby

def rot13(s)

 s.tr('A-Za-z', 'N-ZA-Mn-za-m')

end

alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; puts rot13(alpha)

Output:

NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm

Seed7

This rot13 program reads from standard input and writes to standard output:

$ include "seed7_05.s7i";

const proc: main is func
  local
    var char: ch is ' ';
  begin
    ch := getc(IN);
    while not eof(IN) do
      if (ch >= 'a' and ch <= 'm') or (ch >= 'A' and ch <= 'M') then
        ch := chr(ord(ch) + 13);
      elsif (ch >= 'n' and ch <= 'z') or (ch >= 'N' and ch <= 'Z') then
        ch := chr(ord(ch) - 13);
      end if;
      write(ch);
      ch := getc(IN);
    end while;
  end func;

UNIX Shell

Bourne Shell

#!/bin/sh
function rot13 () {
   tr '[a-m][n-z][A-M][N-Z]' '[n-z][a-m][N-Z][A-M]'
   }
[ "$#" -lt 1 ] && {
   rot13
   } || for eachFile in "$@"; do
            cat "$eachFile" | rot13
            done

UNIX shell assumes availability of the standard UNIX utility commands (in the "coreutils" package on Linux systems, for example); thus the tr (translate) command is trivially provided with the proper arguments to perform the rotations. This example shows proper quoting around "$@" (magical argument list) and "$eachFile" such that this script work properly even if some of the files named on the command line contain embedded spaces or other such characters.

XSLT

Textual transforms are one of the domains XSLT was designed for.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" />
  <xsl:variable name="alpha">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz</xsl:variable>
  <xsl:variable name="rot13">NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm</xsl:variable>  
  <xsl:template match="body"> 
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="rot13">
    <xsl:value-of select="translate(.,$alpha,$rot13)"/>
  </xsl:template>
</xsl:stylesheet>

This will transform the input:

<body>The <rot13>Abjurer</rot13> was to be found <rot13>Nowhere</rot13>.</body>

into:

The Nowhere was to be found Abjurer.