Rot-13: Difference between revisions

From Rosetta Code
Content added Content deleted
(Add Limbo rot13 (Luckily, I had already written/tested this.))
Line 1,569: Line 1,569:
next
next
end function
end function
</lang>

=={{header|Limbo}}==

A fairly straightforward version that uses a lookup table, based on Inferno's cat(1).

<lang Limbo>implement Rot13;

include "sys.m"; sys: Sys;
include "draw.m";

Rot13: module
{
init: fn(ctxt: ref Draw->Context, argv: list of string);
};

stdout: ref Sys->FD;
tab: array of int;

init(nil: ref Draw->Context, args: list of string)
{
sys = load Sys Sys->PATH;
stdout = sys->fildes(1);
inittab();
args = tl args;
if(args == nil)
args = "-" :: nil;
for(; args != nil; args = tl args){
file := hd args;
if(file != "-"){
fd := sys->open(file, Sys->OREAD);
if(fd == nil){
sys->fprint(sys->fildes(2), "rot13: cannot open %s: %r\n", file);
raise "fail:bad open";
}
rot13cat(fd, file);
}else
rot13cat(sys->fildes(0), "<stdin>");
}
}

inittab()
{
tab = array[256] of int;
for(i := 0; i < 256; i++)
tab[i] = i;

for(i = 'a'; i <= 'z'; i++)
tab[i] = (((i - 'a') + 13) % 26) + 'a';
for(i = 'A'; i <= 'Z'; i++)
tab[i] = (((i - 'A') + 13) % 26) + 'A';
}


rot13(s: string): string
{
for(i := 0; i < len s; i++) {
if(s[i] < 256)
s[i] = tab[s[i]];
}
return s;
}

rot13cat(fd: ref Sys->FD, file: string)
{
buf := array[Sys->ATOMICIO] of byte;

while((n := sys->read(fd, buf, len buf)) > 0) {
obuf := array of byte (rot13(string buf));
if(sys->write(stdout, obuf, n) < n) {
sys->fprint(sys->fildes(2), "rot13: write error: %r\n");
raise "fail:write error";
}
}
if(n < 0) {
sys->fprint(sys->fildes(2), "rot13: error reading %s: %r\n", file);
raise "fail:read error";
}
}
</lang>
</lang>



Revision as of 04:26, 2 January 2014

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, e.g., 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 spoiler or 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 its 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" with 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.

6502 Assembly

Written for the BeebAsm assembler, which uses '&' to indicate a hexadecimal number. Call with the address of a zero terminated string in X and Y. On exit X is preserved, Y is the length of the string and A is zero.

<lang 6502asm>buffer = &70  ; or anywhere in zero page that's good

org &1900 .rot13

        stx buffer
        sty buffer+1
        ldy #0

.loop lda (buffer),y

        bne decode        ; quit on ASCII 0
        rts

.decode cmp #&7b  ; high range

        bcs next
        cmp #&41          ; low range
        bcc next
        cmp #&4f
        bcc add13
        cmp #&5b
        bcc sub13
        cmp #&61
        bcc next
        cmp #&6f
        bcc add13
        bcs sub13         ; saves a byte over a jump

.next iny

        jmp loop

.add13 adc #13  ; we only get here via bcc; so clc not needed

        jmp storeit

.sub13 sec

        sbc #13

.storeit sta (buffer),y

        jmp next</lang>

ACL2

<lang lisp>(include-book "arithmetic-3/top" :dir :system)

(defun char-btn (c low high)

  (and (char>= c low)
       (char<= c high)))

(defun rot-13-cs (cs)

  (cond ((endp cs) nil)
        ((or (char-btn (first cs) #\a #\m)
             (char-btn (first cs) #\A #\M))
         (cons (code-char (+ (char-code (first cs)) 13))
               (rot-13-cs (rest cs))))
        ((or (char-btn (first cs) #\n #\z)
             (char-btn (first cs) #\N #\Z))
         (cons (code-char (- (char-code (first cs)) 13))
               (rot-13-cs (rest cs))))
        (t (cons (first cs) (rot-13-cs (rest cs))))))

(defun rot-13 (s)

  (coerce (rot-13-cs (coerce s 'list)) 'string))</lang>

Ada

<lang 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;</lang>

ALGOL 68

Translation of: Modula-3
Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386

<lang algol68>BEGIN

 CHAR c;
 on logical file end(stand in, (REF FILE f)BOOL: (stop; SKIP));
 on line end(stand in, (REF FILE f)BOOL: (print(new line); FALSE));
 DO
   read(c);
   IF c >= "A" AND c <= "M" OR c >= "a" AND c <= "m" THEN
     c := REPR(ABS c + 13)
   ELIF c >= "N" AND c <= "Z" OR c >= "n" AND c <= "z" THEN
     c := REPR(ABS c - 13)
   FI;
   print(c)
 OD

END # rot13 #</lang> Sample run on linux:

$ echo Big fjords vex quick waltz nymph! | a68g Rot-13.a68
Ovt swbeqf irk dhvpx jnygm alzcu!

AppleScript

Using do shell script <lang Applescript>to rot13(textString) do shell script "tr a-zA-Z n-za-mN-ZA-M <<<" & quoted form of textString end rot13</lang> Pure AppleScript solution <lang Applescript>to rot13(textString)

 local outChars
 set outChars to {}
 repeat with ch in (characters of textString)
   if (ch >= "a" and ch <= "m") or (ch >= "A" and ch <= "M") then
     set ch to character id (id of ch + 13)
   else if (ch >= "n" and ch <= "z") or (ch >= "N" and ch <= "Z") then
     set ch to character id (id of ch - 13)
   end
   set end of outChars to ch
 end
 return outChars as text

end rot13 </lang> Demo code: <lang AppleScript>rot13("nowhere ABJURER")</lang> Output:

abjurer NOWHERE

AutoHotkey

Simple alphabet remapping method by Raccoon. Similar to a translate() function in many languages. <lang AutoHotkey>ROT13(string) ; by Raccoon July-2009 {

 Static a := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "
 Static b := "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM "
 s=
 Loop, Parse, string
 {
   c := substr(b,instr(a,A_LoopField,True),1)
   if (c != " ")
     s .= c
   else
     s .= A_LoopField
 }
 Return s

}</lang>

Simple ASCII math method by Raccoon. Add or subtract 13 depending on the character's decimal value. <lang AutoHotkey>ROT13(string) ; by Raccoon July-2009 {

 s=
 Loop, Parse, string
 {
   c := asc(A_LoopField)
   if (c >= 97) && (c <= 109) || (c >= 65) && (c <= 77)
     c += 13
   else if (c >= 110) && (c <= 122) || (c >= 78) && (c <= 90)
     c -= 13
   s .= chr(c)
 }
 Return s

}</lang>

Code modified from stringmod by Hugo: ahk discussion <lang AutoHotkey>Str0=Hello, This is a sample text with 1 2 3 or other digits!@#$^&*()-_= Str1 := Rot13(Str0) Str2 := Rot13(Str1) MsgBox % Str0 "`n" Str1 "`n" Str2

Rot13(string) {

  Loop Parse, string
  {
     char := Asc(A_LoopField)
     ; o is 'A' code if it is an uppercase letter, and 'a' code if it is a lowercase letter
     o := Asc("A") * (Asc("A") <= char && char <= Asc("Z")) + Asc("a") * (Asc("a") <= char && char <= Asc("z"))
     If (o > 0)
     {
        ; Set between 0 and 25, add rotation factor, modulus alphabet size
        char := Mod(char - o + 13, 26)
        ; Transform back to char, upper or lower
        char := Chr(char + o)
     }
     Else
     {
        ; Non alphabetic, unchanged
        char := A_LoopField
     }
     rStr .= char
  }
  Return rStr

}</lang>

AWK

<lang awk>BEGIN {

 for(i=0; i < 256; i++) {
   amap[sprintf("%c", i)] = i
 }
 for(l=amap["a"]; l <= amap["z"]; l++) {
   rot13[l] = sprintf("%c", (((l-amap["a"])+13) % 26 ) + amap["a"])
 }
 FS = ""

} {

 o = ""
 for(i=1; i <= NF; i++) {
   if ( amap[tolower($i)] in rot13 ) {
     c = rot13[amap[tolower($i)]]
     if ( tolower($i) != $i ) c = toupper(c)
     o = o c
   } else {
     o = o $i
   }
 }
 print o

}</lang>

BASIC

Works with: QBasic

<lang qbasic>CLS INPUT "Enter a string: ", s$ ans$ = "" FOR a = 1 TO LEN(s$)

       letter$ = MID$(s$, a, 1)
       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$</lang>

Alternate version

This version does the rotation in-place without the use of a second variable.

<lang qbasic>INPUT "Enter a string "; Text$ FOR c% = 1 TO LEN(Text$)

   SELECT CASE ASC(MID$(Text$, c%, 1))
       CASE 65 TO 90
           MID$(Text$, c%, 1) = CHR$(65 + ((ASC(MID$(Text$, c%, 1)) - 65 + 13) MOD 26))
       CASE 97 TO 122
           MID$(Text$, c%, 1) = CHR$(97 + ((ASC(MID$(Text$, c%, 1)) - 97 + 13) MOD 26))
   END SELECT

NEXT c% PRINT "Converted......: "; Text$</lang>

Sample output:

Enter a string ? Oolite quick Thargoid jumps lazy Vipers = blown up + special fx
Converted......: Bbyvgr dhvpx Gunetbvq whzcf ynml Ivcref = oybja hc + fcrpvny sk

See also: BBC BASIC, FBSL, GW-BASIC, Liberty BASIC, Locomotive Basic, PureBasic, Run BASIC, TI-83 BASIC, Visual Basic .NET, ZX Spectrum Basic

BBC BASIC

<lang bbcbasic> REPEAT

       INPUT A$
       PRINT FNrot13(A$)
     UNTIL FALSE
     END
     
     DEF FNrot13(A$)
     LOCAL A%,B$,C$
     IF A$="" THEN =""
     FOR A%=1 TO LEN A$
       C$=MID$(A$,A%,1)
       IF C$<"A" OR (C$>"Z" AND C$<"a") OR C$>"z" THEN
         B$=B$+C$
       ELSE
         IF (ASC(C$) AND &DF)<ASC("N") THEN
           B$=B$+CHR$(ASC(C$)+13)
         ELSE
           B$=B$+CHR$(ASC(C$)-13)
         ENDIF
       ENDIF
     NEXT A%
     =B$

</lang>

Befunge

<lang befunge>~:"z"`#v_:"m"`#v_:"`"` |>

:"Z"`#v_:"M"`#v_:"@"`|>
: 0 `#v_@v-6-7<      >

, < <+6+7 <<v</lang>

Burlesque

<lang burlesque> blsq ) "HELLO WORLD"{{'A'Zr\\/Fi}m[13?+26.%'A'Zr\\/si}ww "URYYB JBEYQ" blsq ) "URYYB JBEYQ"{{'A'Zr\\/Fi}m[13?+26.%'A'Zr\\/si}ww "HELLO WORLD" </lang>

C

<lang 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;

}</lang>

Alternative version

This version rot13'd lowercase and uppercase letters.

File can be processing simply by piping: <lang bash>cat filename | ./rot13</lang>

<lang c>#include <stdio.h>

  1. include <ctype.h>

char rot13_char(char s);

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

   int c;
   if (argc != 1) {
       fprintf(stderr, "Usage: %s\n", argv[0]);
       return 1;
   }
   while((c = getchar()) != EOF) {
       putchar(rot13_char(c));
   }
   return 0;

}

char rot13_char(char c) {

   if (isalpha(c)) {
       char alpha = islower(c) ? 'a' : 'A';
       return (c - alpha + 13) % 26 + alpha;
   }
   return c;

}</lang>

C#

<lang csharp>using System; using System.IO; using System.Linq; using System.Text;

class Program {

   static char Rot13(char c)
   {
       if ('a' <= c && c <= 'm' || 'A' <= c && c <= 'M')
       {
           return (char)(c + 13);
       }
       if ('n' <= c && c <= 'z' || 'N' <= c && c <= 'Z')
       {
           return (char)(c - 13);
       }
       return c;
   }
   static string Rot13(string s)
   {
       return new StringBuilder().Append(s.Select(Rot13).ToArray()).ToString();
   }


   static void Main(string[] args)
   {
       foreach (var file in args.Where(file => File.Exists(file)))
       {
           Console.WriteLine(Rot13(File.ReadAllText(file)));
       }
       if (!args.Any())
       {
           Console.WriteLine(Rot13(Console.In.ReadToEnd()));
       }
   }

}</lang>

C++

<lang cpp>#include <iostream>

  1. include <istream>
  2. include <ostream>
  3. include <fstream>
  4. include <cstdlib>
  5. 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;

}</lang>

Here is an other approach which can rotate by any number:

Library: Boost

<lang cpp>#include <iostream>

  1. include <string>
  2. include <boost/iostreams/concepts.hpp> // output_filter
  3. include <boost/iostreams/operations.hpp> // put
  4. include <boost/iostreams/filtering_stream.hpp>
  5. include <fstream>

namespace io = boost::iostreams;

class rot_output_filter : public io::output_filter { public:

   explicit rot_output_filter(int r=13):rotby(r),negrot(alphlen-r){};
   template<typename Sink>
   bool put(Sink& dest, int c){
       char uc = toupper(c);
       if(('A' <= uc) && (uc <= ('Z'-rotby)))
           c = c + rotby;
       else if ((('Z'-rotby) <= uc) && (uc <= 'Z'))
           c = c - negrot;
       return boost::iostreams::put(dest, c);
   };

private:

       static const int alphlen = 26;
       const int rotby;
       const int negrot;

};

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

   io::filtering_ostream out;
   out.push(rot_output_filter(13));
   out.push(std::cout);
   if (argc == 1) out << std::cin.rdbuf();
   else for(int i = 1; i < argc; ++i){
       std::ifstream in(argv[i]);
       out << in.rdbuf();
   }

}

</lang>

Clojure

<lang lisp>(defn rot-13 [c]

 (let [i (int c)]
   (cond
     (or (and (>= i (int \a)) (<= i (int \m)))
         (and (>= i (int \A)) (<= i (int \M))))
       (char (+ i 13))
     (or (and (>= i (int \n)) (<= i (int \z)))
         (and (>= i (int \N)) (<= i (int \Z))))
       (char (- i 13))
     :else c)))

(apply str (map rot-13 "abcxyzABCXYZ")) ;; output "nopklmNOPKLM"</lang> An alternative implementation using a closure or two: <lang lisp>(let [A (into #{} "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

     A-map (zipmap A (take 52 (drop 26 (cycle A))))]     
 
 (defn rot13[in-str]
   (reduce str (map #(if (A %1) (A-map %1) %1)  in-str))))

(rot13 "The Quick Brown Fox Jumped Over The Lazy Dog!") ;; produces "Gur Dhvpx Oebja Sbk Whzcrq Bire Gur Ynml Qbt!"</lang>

COBOL

<lang cobol> IDENTIFICATION DIVISION.

      PROGRAM-ID. rot-13.
      DATA DIVISION.
      LOCAL-STORAGE SECTION.
      78  STR-LENGTH   VALUE 100.

      78  normal-lower VALUE "abcdefghijklmnopqrstuvwxyz".
      78  rot13-lower  VALUE "nopqrstuvwxyzabcdefghijklm".
      78  normal-upper VALUE "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
      78  rot13-upper  VALUE "NOPQRSTUVWXYZABCDEFGHIJKLM".
      LINKAGE SECTION.
      01  in-str       PIC X(STR-LENGTH).
      01  out-str      PIC X(STR-LENGTH).
      PROCEDURE DIVISION USING VALUE in-str, REFERENCE out-str.
          MOVE in-str TO out-str
          INSPECT out-str CONVERTING normal-lower TO rot13-lower
          INSPECT out-str CONVERTING normal-upper TO rot13-upper
          GOBACK
          .</lang>

Common Lisp

The standard gives implementations great leeway with respect to character encodings, so we can't rely on the convenient properties of ASCII. <lang lisp>(defconstant +alphabet+ '(#\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P

 #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z))

(defun rot13 (s)

 (map 'string
   (lambda (c &aux (n (position (char-upcase c) +alphabet+)))
     (if n
       (funcall
         (if (lower-case-p c) #'char-downcase #'identity)
         (nth (mod (+ 13 n) 26) +alphabet+))
       c))
   s))</lang>

Assuming ASCII Character Set

Though the standard intentionally doesn't specify encoding, every popular implementation today uses ASCII. <lang lisp>(defun rot13 (string)

 (map 'string
      (lambda (char &aux (code (char-code char)))
        (if (alpha-char-p char)
            (if (> (- code (char-code (if (upper-case-p char)
                                          #\A #\a))) 12)
                (code-char (- code 13))
                (code-char (+ code 13)))
            char))
      string))

(rot13 "Moron") ; -> "Zbeba"</lang>

Cubescript

<lang cubescript>alias rot13 [ push alpha [ "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z" "a b c d e f g h i j k l m n o p q r s t u v w x y z" ] [ push chars [] [ loop i (strlen $arg1) [ looplist n $alpha [ if (! (listlen $chars)) [ alias chars (? (> (listindex $n (substr $arg1 $i 1)) -1) $n []) ] ] alias arg1 ( concatword (substr $arg1 0 $i) ( ? (listlen $chars) ( at $chars ( mod (+ ( listindex $chars (substr $arg1 $i 1) ) 13 ) (listlen $chars) ) ) (substr $arg1 $i 1) ) (substr $arg1 (+ $i 1) (strlen $arg1)) ) alias chars [] ] ] ] result $arg1 ]</lang>

Usage: <lang cubescript>>>> rot13 "Hello World" > Uryyb Jbeyq >>> rot13 "Gur Dhvpx Oebja Sbk Whzcf Bire Gur Ynml Qbt!" > The Quick Brown Fox Jumps Over The Lazy Dog!</lang>

D

Using Standard Functions

<lang d>import std.stdio; import std.ascii: letters, U = uppercase, L = lowercase; import std.string: makeTrans, translate;

immutable r13 = makeTrans(letters,

                         //U[13 .. $] ~ U[0 .. 13] ~
                         U[13 .. U.length] ~ U[0 .. 13] ~
                         L[13 .. L.length] ~ L[0 .. 13]);

void main() {

   writeln("This is the 1st test!".translate(r13, null));

}</lang>

Output:
The Quick Brown Fox Jumps Over The Lazy Dog!

Imperative Implementation

<lang d>import std.stdio, std.string, std.traits;

pure S rot13(S)(in S s) if (isSomeString!S) {

   return rot(s, 13);

}

pure S rot(S)(in S s, in int key) if (isSomeString!S) {

   auto r = s.dup;
   foreach (i, ref c; r) {
       if ('a' <= c && c <= 'z')
           c = ((c - 'a' + key) % 26 + 'a');
       else if ('A' <= c && c <= 'Z')
           c = ((c - 'A' + key) % 26 + 'A');
   }
   return cast(S) r;

}

void main() {

   "Gur Dhvpx Oebja Sbk Whzcf Bire Gur Ynml Qbt!".rot13().writeln();

}</lang>

Déjà Vu

<lang dejavu>rot-13: ) for ch in chars swap: ord ch if <= 65 dup: if >= 90 dup: + 13 - swap 65 + 65 % swap 26 if <= 97 dup: if >= 122 dup: + 13 - swap 97 + 97 % swap 26 chr concat(

!print rot-13 "Snape kills Frodo with Rosebud."</lang>

Output:
Fancr xvyyf Sebqb jvgu Ebfrohq.

E

<lang e>pragma.enable("accumulator")

var rot13Map := [].asMap() for a in ['a', 'A'] {

   for i in 0..!26 {
       rot13Map with= (a + i, E.toString(a + (i + 13) % 26))
   }

}

def rot13(s :String) {

 return accum "" for c in s { _ + rot13Map.fetch(c, fn{ c }) }

}</lang>

Erlang

<lang erlang>rot13(Str) ->

   F = fun(C) when (C >= $A andalso C =< $M); (C >= $a andalso C =< $m) -> C + 13;
          (C) when (C >= $N andalso C =< $Z); (C >= $n andalso C =< $z) -> C - 13;
          (C) -> C
       end,
   lists:map(F, Str).</lang>

Euphoria

Works with: Euphoria version 4.0.0

<lang Euphoria> include std/types.e include std/text.e

atom FALSE = 0 atom TRUE = not FALSE

function Rot13( object oStuff ) integer iOffset integer bIsUpper object oResult sequence sAlphabet = "abcdefghijklmnopqrstuvwxyz" if sequence(oStuff) then oResult = repeat( 0, length( oStuff ) ) for i = 1 to length( oStuff ) do oResult[ i ] = Rot13( oStuff[ i ] ) end for else bIsUpper = FALSE if t_upper( oStuff ) then bIsUpper = TRUE oStuff = lower( oStuff ) end if iOffset = find( oStuff, sAlphabet ) if iOffset != 0 then iOffset += 13 iOffset = remainder( iOffset, 26 ) if iOffset = 0 then iOffset = 1 end if oResult = sAlphabet[iOffset] if bIsUpper then oResult = upper(oResult) end if else oResult = oStuff --sprintf( "%s", oStuff ) end if end if return oResult end function

puts( 1, Rot13( "abjurer NOWHERE." ) & "\n" ) </lang>

F#

Illustrates turning a string into an array of chars then composition of type casting with a conversion function. We create a composite that converts its input to an integer, calls the convertion function and then casts to a char type. The result is an array of modified chars that we can use to create a new string. <lang fsharp>let rot13 (s : string) =

  let rot c =
      match c with
      | c when c > 64 && c < 91 -> ((c - 65 + 13) % 26) + 65
      | c when c > 96 && c < 123 -> ((c - 97 + 13) % 26) + 97
      | _ -> c
  s |> Array.of_seq
  |> Array.map(int >> rot >> char)
  |> (fun seq -> new string(seq))</lang>

Factor

<lang factor>#! /usr/bin/env factor

USING: kernel io ascii math combinators sequences ; IN: rot13

rot-base ( ch ch -- ch ) [ - 13 + 26 mod ] keep + ;
rot13-ch ( ch -- ch )
   {
       { [ dup letter? ] [ CHAR: a rot-base ] }
       { [ dup LETTER? ] [ CHAR: A rot-base ] }
       [ ]
   }
   cond ;
rot13 ( str -- str ) [ rot13-ch ] map ;
main ( -- )
   [ readln dup ]
   [ rot13 print flush ]
   while
   drop ;

MAIN: main</lang>

FALSE

<lang false>[^$1+][$32|$$'z>'a@>|$[\%]?~[13\'m>[_]?+]?,]#%</lang>

Fantom

<lang fantom> class Rot13 {

 static Str rot13 (Str input)
 {
   Str result := ""
   input.each |Int c|
   {
     if ((c.lower >= 'a') && (c.lower <= 'm'))
       result += (c+13).toChar
     else if ((c.lower >= 'n') && (c.lower <= 'z'))
       result += (c-13).toChar
     else
       result += c.toChar
   }
   return result
 }
 public static Void main (Str[] args)
 {
   if (args.size == 1)
   { // process each line of given file
     Str filename := args[0]
     File(filename.toUri).eachLine |Str line|
     {
       echo (rot13(line))
     }
   }
   else
   {
     echo ("Test:")
     Str text := "abcstuABCSTU123!+-"
     echo ("Text $text becomes ${rot13(text)}")
   }
 }

} </lang>

FBSL

Implements a circular queue, finds the required character and then rotates the queue forward 13 places. Would do as a solution to Caesar Cipher with a different rotation number. Please note that FBSL is not case sensitive, thus the use of lstrcmp. <lang qbasic>#APPTYPE CONSOLE

REM Create a CircularQueue object REM CQ.Store item REM CQ.Find items REM CQ.Forward nItems REM CQ.Recall

REM SO CQ init WITH "A"... "Z" REM CQ.Find "B" REM QC.Forward 13 REM QC.Recall

CLASS CircularQueue items[] head tail here

SUB INITIALIZE(dArray) head = 0 tail = 0 here = 0 FOR DIM i = LBOUND(dArray) TO UBOUND(dArray) items[tail] = dArray[i] tail = tail + 1 NEXT END SUB

SUB TERMINATE() REM END SUB

METHOD Put(s AS STRING) items[tail] = s tail = tail + 1 END METHOD

METHOD Find(s AS STRING) FOR DIM i = head TO tail - 1 IF items[i] = s THEN here = i RETURN TRUE END IF NEXT RETURN FALSE END METHOD

METHOD Move(n AS INTEGER) DIM bound AS INTEGER = UBOUND(items) + 1 here = (here + n) MOD bound END METHOD

METHOD Recall() RETURN items[here] END METHOD

PROPERTY Size() RETURN COUNT(items) END PROPERTY END CLASS

DIM CQ AS NEW CircularQueue({"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"})

DIM c AS STRING DIM isUppercase AS INTEGER DIM s AS STRING = "nowhere ABJURER"

FOR DIM i = 1 TO LEN(s) c = MID(s, i, 1) isUppercase = lstrcmp(LCASE(c), c) IF CQ.Find(UCASE(c)) THEN CQ.Move(13) PRINT IIF(isUppercase, UCASE(CQ.Recall()), LCASE(CQ.Recall())) ; ELSE PRINT c; END IF NEXT

PAUSE </lang>

Forth

A simple version, using nested conditionals. <lang forth>: 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 ;</lang>

A table driven version which should be more efficient. The mechanism is flexible enough to express any sort of transform. <lang forth>: ,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</lang>

Fortran

Works with: Fortran version 90 and later

<lang fortran>program test_rot_13

 implicit none
 integer, parameter :: len_max = 256
 integer, parameter :: unit = 10
 character (len_max) :: file
 character (len_max) :: fmt
 character (len_max) :: line
 integer :: arg
 integer :: arg_max
 integer :: iostat
 write (fmt, '(a, i0, a)') '(a', len_max, ')'
 arg_max = iargc ()
 if (arg_max > 0) then

! Encode all files listed on the command line.

   do arg = 1, arg_max
     call getarg (arg, file)
     open (unit, file = file, iostat = iostat)
     if (iostat /= 0) cycle
     do
       read (unit, fmt = fmt, iostat = iostat) line
       if (iostat /= 0) exit
       write (*, '(a)') trim (rot_13 (line))
     end do
     close (unit)
   end do
 else

! Encode standard input.

   do
     read (*, fmt = fmt, iostat = iostat) line
     if (iostat /= 0) exit
     write (*, '(a)') trim (rot_13 (line))
   end do
 end if

contains

 function rot_13 (input) result (output)
   implicit none
   character (len_max), intent (in) :: input
   character (len_max) :: output
   integer :: i
   output = input
   do i = 1, len_trim (output)
     select case (output (i : i))
     case ('A' : 'M', 'a' : 'm')
       output (i : i) = char (ichar (output (i : i)) + 13)
     case ('N' : 'Z', 'n' : 'z')
       output (i : i) = char (ichar (output (i : i)) - 13)
     end select
   end do
 end function rot_13

end program test_rot_13</lang> Note: iargc and getarg are common extensions that are implemented by e.g. the Intel Fortran Compiler, G95 and gfortran.

Sample usage: <lang>> cat foo.txt foo > cat bar.txt bar > ./rot_13 foo.txt bar.txt sbb one > ./rot_13 < foo.txt sbb > cat foo.txt bar.txt | ./rot_13 sbb one</lang>

GAP

<lang gap>rot13 := function(s)

 local upper, lower, c, n, t;
 upper := "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 lower := "abcdefghijklmnopqrstuvwxyz";
 t := [ ];
 for c in s do
   n := Position(upper, c);
   if n <> fail then
     Add(t, upper[((n+12) mod 26) + 1]);
   else
     n := Position(lower, c);
     if n <> fail then
       Add(t, lower[((n+12) mod 26) + 1]);
     else
       Add(t, c);
     fi;
   fi;
 od;
 return t;

end;

a := "England expects that every man will do his duty";

  1. "England expects that every man will do his duty"

b := rot13(a);

  1. "Ratynaq rkcrpgf gung rirel zna jvyy qb uvf qhgl"

c := rot13(b);

  1. "England expects that every man will do his duty"</lang>

Gema

<lang gema>/[a-mA-M]/=@int-char{@add{@char-int{$1};13}} /[n-zN-Z]/=@int-char{@sub{@char-int{$1};13}}</lang>

GML

<lang GML>#define rot13 var in, out, i, working; in = argument0; out = ""; for (i = 1; i <= string_length(in); i += 1)

   {
   working = ord(string_char_at(in, i));
   if ((working > 64) && (working < 91))
       {
       working += 13;
       if (working > 90)
           {
           working -= 26;
           }
       }
   else if ((working > 96) && (working < 123))
       {
       working += 13;
       if (working > 122) working -= 26;
       }
   out += chr(working);
   }

return out;</lang>

The above code is called like this: <lang GML>show_message(rot13("My dog has fleas!"));</lang>

Output (in a message box):

Zl qbt unf syrnf!

Go

<lang go>package main

import (

   "fmt"
   "strings"

)

func rot13char(c rune) rune {

   if c >= 'a' && c <= 'm' || c >= 'A' && c <= 'M' {
       return c + 13
   } else if c >= 'n' && c <= 'z' || c >= 'N' && c <= 'Z' {
       return c - 13
   }
   return c

}

func rot13(s string) string {

   return strings.Map(rot13char, s)

}

func main() {

   fmt.Println(rot13("nowhere ABJURER"))

}</lang> Output:

abjurer NOWHERE

Groovy

Solution: <lang groovy>def rot13 = { String s ->

   (s as List).collect { ch ->
       switch (ch) {
           case ('a'..'m') + ('A'..'M'):
               return (((ch as char) + 13) as char)
           case ('n'..'z') + ('N'..'Z'):
               return (((ch as char) - 13) as char)
           default:
               return ch
       }
   }.inject ("") { string, ch -> string += ch}

}</lang>

Test program: <lang groovy>println rot13("Noyr jnf V, 'rer V fnj Ryon.")</lang>

Output:

Able was I, 'ere I saw Elba.

GW-BASIC

<lang qbasic>10 INPUT "Enter a string: ",A$ 20 GOSUB 50 30 PRINT B$ 40 END 50 FOR I=1 TO LEN(A$) 60 N=ASC(MID$(A$,I,1)) 70 E=255 80 IF N>64 AND N<91 THEN E=90 ' uppercase 90 IF N>96 AND N<123 THEN E=122 ' lowercase 100 IF E<255 THEN N=N+13 110 IF N>E THEN N=N-26 120 B$=B$+CHR$(N) 130 NEXT 140 RETURN</lang>

Haskell

Straightforward implementation by checking multiple cases:

<lang haskell>import Data.Char

rot13 :: Char -> Char rot13 c

 | toLower c >= 'a' && toLower c <= 'm' = chr (ord c + 13)
 | toLower c >= 'n' && toLower c <= 'z' = chr (ord c - 13)
 | otherwise = c</lang>

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

<lang haskell>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</lang>

Then the wrapped program is simply <lang haskell>main = do

names <- getArgs
process (hInteract (map rot13)) names</lang>

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

HicEst

<lang hicest>CHARACTER c, txt='abc? XYZ!', cod*100

 DO i = 1, LEN_TRIM(txt)
   c = txt(i)
   n = ICHAR(txt(i))
   IF( (c >= 'a') * (c <= 'm') + (c >= 'A') * (c <= 'M') ) THEN
       c = CHAR( ICHAR(c) + 13 )
   ELSEIF( (c >= 'n') * (c <= 'z') + (c >= 'N') * (c <= 'Z') ) THEN
       c = CHAR( ICHAR(c) - 13 )
   ENDIF
   cod(i) = c
 ENDDO
 WRITE(ClipBoard, Name) txt, cod ! txt=abc? XYZ!; cod=nop? KLM!;

END</lang>

Icon and Unicon

<lang Icon>procedure main(arglist)

  file := open(arglist[1],"r") | &input
  every write(rot13(|read(file)))

end

procedure rot13(s) #: returns rot13(string) static a,n initial {

  a := &lcase || &ucase
  (&lcase || &lcase) ? n := ( move(13), move(*&lcase) )
  (&ucase || &ucase) ? n ||:= ( move(13), move(*&ucase) )
  }

return map(s,a,n) end</lang> This example uses a number of Icon features.

  • alternation ( x | y ) selects and opens a file if supplied or fall back to standard output
  • repeated alternation ( |x ) is used to generate the contents of the input file
  • the rot13 procedure does a one time setup (initially) of persistent (static) mapping strings so the procedure can return the rot13 mapping
  • the setup exploits the ordered cset variables &lcase and &ucase coercing them into strings
  • the rot13 mapping string is then aggregated with strings taken by offsetting into double length values to avoid unnecessary and messy rotation

J

<lang j>rot13=: {&((65 97+/~i.2 13) |.@[} i.256)&.(a.&i.)</lang>

For example:

   rot13 'abc! ABC!'
nop! NOP!

Compare with the solution to the Change String Case task.

Java

<lang java>import java.io.*;

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 (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) {
       StringBuilder retVal = new StringBuilder();
       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.append(a);
       }
       return retVal.toString();
   }

}</lang>

JavaScript

<lang javascript>function rot13(c) {

   return c.replace(/([a-m])|([n-z])/ig, function($0,$1,$2) {
       return String.fromCharCode($1 ? $1.charCodeAt(0) + 13 : $2 ? $2.charCodeAt(0) - 13 : 0) || $0;
   });

} rot13("ABJURER nowhere") // NOWHERE abjurer </lang>

TDD with Jasmine using Underscore.js

<lang javascript> function rot13(value){

 if (!value)
   return "";
 function singleChar(c) {
   if (c.toUpperCase() < "A" || c.toUpperCase() > "Z")
     return c;
   if (c.toUpperCase() <= "M")
     return String.fromCharCode(c.charCodeAt(0) + 13);
   return String.fromCharCode(c.charCodeAt(0) - 13);  
 }
 return _.map(value.split(""), singleChar).join("");

}

describe("Rot-13", function() {

 it("Given nothing will return nothing", function() {
   expect(rot13()).toBe("");
 });
 it("Given empty string will return empty string", function() {
   expect(rot13("")).toBe("");
 });
 it("Given A will return N", function() {
   expect(rot13("A")).toBe("N");
 });
 it("Given B will return O", function() {
   expect(rot13("B")).toBe("O");
 });
 it("Given N will return A", function() {
   expect(rot13("N")).toBe("A");
 });
 it("Given Z will return M", function() {
   expect(rot13("Z")).toBe("M");
 });
 it("Given ZA will return MN", function() {
   expect(rot13("ZA")).toBe("MN");
 });
 it("Given HELLO will return URYYB", function() {
   expect(rot13("HELLO")).toBe("URYYB");
 });
 it("Given hello will return uryyb", function() {
   expect(rot13("hello")).toBe("uryyb");
 });


 it("Given hello1 will return uryyb1", function() {
   expect(rot13("hello1")).toBe("uryyb1");
 });

}); </lang>

Julia

<lang Julia>function rot13(c::Char)

 c in 'a':'z' ?  'a' + (c - 'a' + 13)%26 :
 c in 'A':'Z' ?  'A' + (c - 'A' + 13)%26 :
 c

end

rot13(s::String) = map(rot13,CharString(s...))</lang>

Output:
julia> rot13("abcdefghijklmnopqrtuvwxyz 123 ABCDEFGHIJKLMNOPQRTUVWXYZ")
"nopqrstuvwxyzabcdeghijklm 123 NOPQRSTUVWXYZABCDEGHIJKLM"

K

<lang k> rot13: {a:+65 97+\:2 13#!26;_ci@[!256;a;:;|a]_ic x}

 rot13 "Testing! 1 2 3"

"Grfgvat! 1 2 3"</lang>


LabVIEW

This image is a VI Snippet, an executable image of LabVIEW code. The LabVIEW version is shown on the top-right hand corner. You can download it, then drag-and-drop it onto the LabVIEW block diagram from a file browser, and it will appear as runnable, editable code.

Lasso

<lang Lasso>// Extend the string type

define string->rot13 => {

   local(
       rot13 = bytes,
       i, a, b
   )
   with char in .eachCharacter
   let int = #char->integer
   do {
       // We only modify these ranges, set range if we should modify
       #int >= 65 and #int < 91  ? local(a=65,b=91)  |
       #int >= 97 and #int < 123 ? local(a=97,b=123) | local(a=0,b=0)
  
       if(#a && #b) => {
           #i = (#int+13) % #b         // loop back if past ceiling (#b)
           #i += #a * (1 - #i / #a)    // offset if below floor (#a)
           #rot13->import8bits(#i)     // import the new character
       else
           #rot13->append(#char)       // just append the character
       }
   }
   return #rot13->asstring

}</lang>

Example
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'->rot13

'Where do you find a dog with no legs?
Evtug jurer lbh yrsg uvz.'->rot13
Output:
NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm

Jurer qb lbh svaq n qbt jvgu ab yrtf? 
Right where you left him.
Another implementation

<lang Lasso>define rot13(p::string) => {

   local(
       rot13 = bytes,
       a = bytes('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'),
       b = bytes('NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm'),
       i
   )
   with char in #p->eachCharacter 
   let c = bytes(#char) do {
       #i = #a->find(#b)
       #i ? #rot13->import8bits(#b->get(#i)) | #rot13->append(#c)
   }
   
   return #rot13->asString

}

rot13('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')</lang>

Output:
NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm

Liberty BASIC

Liberty BASIC string comparisons are not ascii-based. Verbose version: <lang lb>input "Type some text to be encoded, then ENTER. ";tx$

tex$ = Rot13$(tx$) print tex$ 'check print Rot13$(tex$)

wait

Function Rot13$(t$)

   if t$="" then
       Rot13$=""
       exit function
   end if
   for i = 1 to len(t$)
       c$=mid$(t$,i,1)
       ch$=c$
       if (asc(c$)>=asc("A")) and (asc(c$)<=asc("Z")) then
           ch$=chr$(asc(c$)+13)
           if (asc(ch$)>asc("Z")) then ch$=chr$(asc(ch$)-26)
       end if
       if (asc(c$)>=asc("a")) and (asc(c$)<=asc("z")) then
           ch$=chr$(asc(c$)+13)
           if (asc(ch$)>asc("z")) then ch$=chr$(asc(ch$)-26)
       end if
       rot$=rot$+ch$
   next
   Rot13$=rot$
   end function
</lang>

Concise: <lang lb>Function Rot13$(t$)

   for i = 1 to len(t$)
       ch$=mid$(t$,i,1)
       if (asc(ch$)>=asc("A")) and (asc(ch$)<=asc("Z")) then
           ch$=chr$(asc("A")+ (asc(ch$)-asc("A")+13) mod 26)
       end if
       if (asc(ch$)>=asc("a")) and (asc(ch$)<=asc("z")) then
           ch$=chr$(asc("a")+ (asc(ch$)-asc("a")+13) mod 26)
       end if
       Rot13$=Rot13$+ch$
   next
   end function

</lang>

Limbo

A fairly straightforward version that uses a lookup table, based on Inferno's cat(1).

<lang Limbo>implement Rot13;

include "sys.m"; sys: Sys; include "draw.m";

Rot13: module { init: fn(ctxt: ref Draw->Context, argv: list of string); };

stdout: ref Sys->FD; tab: array of int;

init(nil: ref Draw->Context, args: list of string) { sys = load Sys Sys->PATH; stdout = sys->fildes(1); inittab(); args = tl args; if(args == nil) args = "-" :: nil; for(; args != nil; args = tl args){ file := hd args; if(file != "-"){ fd := sys->open(file, Sys->OREAD); if(fd == nil){ sys->fprint(sys->fildes(2), "rot13: cannot open %s: %r\n", file); raise "fail:bad open"; } rot13cat(fd, file); }else rot13cat(sys->fildes(0), "<stdin>"); } }

inittab() { tab = array[256] of int; for(i := 0; i < 256; i++) tab[i] = i;

for(i = 'a'; i <= 'z'; i++) tab[i] = (((i - 'a') + 13) % 26) + 'a'; for(i = 'A'; i <= 'Z'; i++) tab[i] = (((i - 'A') + 13) % 26) + 'A'; }


rot13(s: string): string { for(i := 0; i < len s; i++) { if(s[i] < 256) s[i] = tab[s[i]]; } return s; }

rot13cat(fd: ref Sys->FD, file: string) { buf := array[Sys->ATOMICIO] of byte;

while((n := sys->read(fd, buf, len buf)) > 0) { obuf := array of byte (rot13(string buf)); if(sys->write(stdout, obuf, n) < n) { sys->fprint(sys->fildes(2), "rot13: write error: %r\n"); raise "fail:write error"; } } if(n < 0) { sys->fprint(sys->fildes(2), "rot13: error reading %s: %r\n", file); raise "fail:read error"; } } </lang>

LiveCode

<lang LiveCode>function rot13 S

  repeat with i = 1 to length(S)
     get chartonum(char i of S)
     if it < 65 or it > 122 or (it > 90 and it < 97) then next repeat 
     put char it - 64 of "NOPQRSTUVWXYZABCDEFGHIJKLM      nopqrstuvwxyzabcdefghijklm" into char i of S
  end repeat
  return S

end rot13</lang>


Locomotive Basic

<lang locobasic>10 INPUT "Enter a string: ",a$ 20 GOSUB 50 30 PRINT b$ 40 END 50 FOR i=1 TO LEN(a$) 60 n=ASC(MID$(a$,i,1)) 70 e=255 80 IF n>64 AND n<91 THEN e=90 ' uppercase 90 IF n>96 AND n<123 THEN e=122 ' lowercase 100 IF e<255 THEN n=n+13 110 IF n>e THEN n=n-26 120 b$=b$+CHR$(n) 130 NEXT 140 RETURN</lang>

<lang logo>to rot13 :c

 make "a difference ascii lowercase :c  ascii "a
 if or :a < 0 :a > 25 [output :c]
 make "delta ifelse :a < 13 [13] [-13]
 output char sum :delta ascii :c

end

print map "rot13 "|abjurer NOWHERE| nowhere ABJURER</lang>

Lua

<lang lua>function rot(l, o) return (l < 26 and l > -1) and string.char((l+13)%26 + o) end a, A = string.byte'a', string.byte'A' val = io.read() val = val:gsub("(.)", function(l) return rot(l:byte()-a,a) or rot(l:byte()-A,A) or l end) print(val)</lang>

Maple

There is a built-in command for this in Maple. <lang Maple>> StringTools:-Encode( "The Quick Brown Fox Jumped Over The Lazy Dog!", encoding = rot13 );

           "Gur Dhvpx Oebja Sbk Whzcrq Bire Gur Ynml Qbt!"</lang>

Mathematica

<lang Mathematica>ruleslower=Thread[#-> RotateLeft[#, 13]]&[CharacterRange["a", "z"]]; rulesupper=Thread[#-> RotateLeft[#, 13]]&[CharacterRange["A", "Z"]]; rules=Join[ruleslower,rulesupper]; text="Hello World! Are you there!?" text=StringReplace[text,rules] text=StringReplace[text,rules]</lang> gives back:

Hello World! Are you there!?
Uryyb Jbeyq! Ner lbh gurer!?
Hello World! Are you there!?

MATLAB

<lang matlab>function r=rot13(s)

   if ischar(s)
       r=s;  % preallocation and copy of non-letters
       for i=1:size(s,1)
           for j=1:size(s,2)
               if isletter(s(i,j))
                   if s(i,j)>=97   % lower case
                       base = 97;
                   else            % upper case
                       base = 65;
                   end
                   r(i,j)=char(mod(s(i,j)-base+13,26)+base);
               end
           end
       end
   else
       error('Argument must be a CHAR')
   end

end</lang> Call it like this: <lang matlab>>> rot13('Hello World!')

ans =

Uryyb Jbeyq!</lang>

It is possible to vectorize this code, the example below is not fully vectorized in order to make the order of operations clear. It is possible to reduce this solution to two lines by integrating the "selectedLetters" calculations directly into the line following them.

<lang MATLAB>function text = rot13(text)

   if ischar(text)
       
       selectedLetters = ( (text >= 'A') & (text <= 'Z') ); %Select upper case letters
       text(selectedLetters) = char( mod( text(selectedLetters)-'A'+13,26 )+'A' );
       
       selectedLetters = ( (text >= 'a') & (text <= 'z') ); %Select lower case letters
       text(selectedLetters) = char( mod( text(selectedLetters)-'a'+13,26 )+'a' );
   else
       error('Argument must be a string.')
   end

end</lang>

Sample Output: <lang MATLAB>>> plainText = char((64:123))

plainText =

@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{

>> rot13(plainText)

ans =

@NOPQRSTUVWXYZABCDEFGHIJKLM[\]^_`nopqrstuvwxyzabcdefghijklm{</lang>

Maxima

<lang maxima>rot13(a) := simplode(map(ascii, map(lambda([n],

     if (n >= 65 and n <= 77) or (n >= 97 and n <= 109) then n + 13
     elseif (n >= 78 and n <= 90) or (n >= 110 and n <= 122) then n - 13
     else n), map(cint, sexplode(a)))))$

lowercase: "abcdefghijklmnopqrstuvwxyz"$ uppercase: "ABCDEFGHIJKLMNOPQRSTUVWXYZ"$

rot13(lowercase); "nopqrstuvwxyzabcdefghijklm"

rot13(uppercase); "NOPQRSTUVWXYZABCDEFGHIJKLM"

rot13("The quick brown fox jumps over the lazy dog"); "Gur dhvpx oebja sbk whzcf bire gur ynml qbt"

rot13(%); "The quick brown fox jumps over the lazy dog"</lang>

Mirah

<lang mirah>def rot13 (value:string)

   result = ""
   d = ' '.toCharArray[0]
   value.toCharArray.each do |c|
       testChar = Character.toLowerCase(c)
       if testChar <= 'm'.toCharArray[0] && testChar >= 'a'.toCharArray[0] then 
           d = char(c + 13)
       end
       if testChar <= 'z'.toCharArray[0] && testChar >= 'n'.toCharArray[0] then 
           d = char(c - 13) 
       end 
       result += d
   end 
   result

end


puts rot13("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")</lang>

MMIX

<lang mmix>// main registers p IS $255 % text pointer c GREG % char cc GREG % uppercase copy of c u GREG % all purpose

LOC Data_Segment GREG @ Test BYTE "dit is een bericht voor de keizer",#a,0

LOC #100 Main LDA p,Test TRAP 0,Fputs,StdOut % show text to encrypt LDA p,Test % points to text to encrypt JMP 4F // do in place text encryption % REPEAT 2H ADD cc,c,0 % copy char SUB cc,cc,' ' % make uppercase CMP u,cc,'A' BN u,3F % IF c < 'A' OR c > 'Z' THEN next char CMP u,cc,'Z' BP u,3F CMP u,cc,'N' % ELSE BN u,1F % IF c < 'N' THEN encrypt 'up' SUB c,c,26 % ELSE char ready for encrypt 'down' 1H INCL c,13 % encrypt char STBU c,p % replace char with encrypted char 3H INCL p,1 % move to next char 4H LDBU c,p % get next char PBNZ c,2B % UNTIL EOT // print result LDA p,Test TRAP 0,Fputs,StdOut % show encrypted text TRAP 0,Halt,0</lang> Example:

~/MIX/MMIX/Progs> mmix rot13simpl
dit is een bericht voor de keizer
qvg vf rra orevpug ibbe qr xrvmre

Modula-3

This implementation reads from stdin and writes to stdout. <lang modula3>MODULE Rot13 EXPORTS Main;

IMPORT Stdio, Rd, Wr;

VAR c: CHAR;

<*FATAL ANY*>

BEGIN

 WHILE NOT Rd.EOF(Stdio.stdin) DO
   c := Rd.GetChar(Stdio.stdin);
   IF c >= 'A' AND c <= 'M' OR c >= 'a' AND c <= 'm' THEN
     c := VAL(ORD((ORD(c) + 13)), CHAR);
   ELSIF c >= 'N' AND c <= 'Z' OR c >= 'n' AND c <= 'z' THEN
     c := VAL(ORD((ORD(c) - 13)), CHAR);
   END;
   Wr.PutChar(Stdio.stdout, c);
 END;

END Rot13.</lang>

Output:

martin@thinkpad:~$ ./prog
Foo bar baz
Sbb one onm
martin@thinkpad:~$ echo "Bar baz foo" | ./prog
One onm sbb
martin@thinkpad:~$ echo "Foo bar baz" > foo.txt 
martin@thinkpad:~$ echo "quux zeepf" >> foo.txt 
martin@thinkpad:~$ cat foo.txt | ./prog
Sbb one onm
dhhk mrrcs

MUMPS

<lang MUMPS>Rot13(in) New low,rot,up Set up="ABCDEFGHIJKLMNOPQRSTUVWXYZ" Set low="abcdefghijklmnopqrstuvwxyz" Set rot=$Extract(up,14,26)_$Extract(up,1,13) Set rot=rot_$Extract(low,14,26)_$Extract(low,1,13) Quit $Translate(in,up_low,rot)

Write $$Rot13("Hello World!") ; Uryyb Jbeyq! Write $$Rot13("ABCDEFGHIJKLMNOPQRSTUVWXYZ") ; NOPQRSTUVWXYZABCDEFGHIJKLM</lang>

NetRexx

This sample leverages the code demonstrated in the Caesar cipher – NetRexx task. <lang NetRexx>/* NetRexx */ options replace format comments java crossref savelog symbols nobinary

parse arg fileNames

rdr = BufferedReader

do

 if fileNames.length > 0 then do
   loop n_ = 1 for fileNames.words
     fileName = fileNames.word(n_)
     rdr = BufferedReader(FileReader(File(fileName)))
     encipher(rdr)
     end n_
   end
 else do
   rdr = BufferedReader(InputStreamReader(System.in))
   encipher(rdr)
   end

catch ex = IOException

 ex.printStackTrace

end

return

method encipher(rdr = BufferedReader) public static signals IOException

 loop label l_ forever
   line = rdr.readLine
   if line = null then leave l_
   say rot13(line)
   end l_
 return

method rot13(input) public static signals IllegalArgumentException

 return caesar(input, 13, isFalse)

method caesar(input = Rexx, idx = int, caps = boolean) public static signals IllegalArgumentException

 if idx < 1 | idx > 25 then signal IllegalArgumentException()
 --      12345678901234567890123456
 itab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 shift = itab.length - idx
 parse itab tl +(shift) tr
 otab = tr || tl
 if caps then input = input.upper
 cipher = input.translate(itab || itab.lower, otab || otab.lower)
 return cipher

method caesar_encipher(input = Rexx, idx = int, caps = boolean) public static signals IllegalArgumentException

 return caesar(input, idx, caps)

method caesar_decipher(input = Rexx, idx = int, caps = boolean) public static signals IllegalArgumentException

 return caesar(input, int(26) - idx, isFalse)

method caesar_encipher(input = Rexx, idx = int) public static signals IllegalArgumentException

 return caesar(input, idx, isFalse)

method caesar_decipher(input = Rexx, idx = int) public static signals IllegalArgumentException

 return caesar(input, int(26) - idx, isFalse)

method caesar_encipher(input = Rexx, idx = int, opt = Rexx) public static signals IllegalArgumentException

 return caesar(input, idx, opt)

method caesar_decipher(input = Rexx, idx = int, opt = Rexx) public static signals IllegalArgumentException

 return caesar(input, int(26) - idx, opt)

method caesar(input = Rexx, idx = int, opt = Rexx) public static signals IllegalArgumentException

 if opt.upper.abbrev('U') >= 1 then caps = isTrue
 else                               caps = isFalse
 return caesar(input, idx, caps)

method caesar(input = Rexx, idx = int) public static signals IllegalArgumentException

 return caesar(input, idx, isFalse)

method isTrue public static returns boolean

 return (1 == 1)

method isFalse public static returns boolean

 return \isTrue

</lang>

Output (using the source file as input):

/* ArgErkk */
bcgvbaf ercynpr sbezng pbzzragf wnin pebffers fnirybt flzobyf abovanel

cnefr net svyrAnzrf

eqe = OhssrerqErnqre

qb
  vs svyrAnzrf.yratgu > 0 gura qb
    ybbc a_ = 1 sbe svyrAnzrf.jbeqf
      svyrAnzr = svyrAnzrf.jbeq(a_)
      eqe = OhssrerqErnqre(SvyrErnqre(Svyr(svyrAnzr)))
      rapvcure(eqe)
      raq a_
    raq
  ryfr qb
    eqe = OhssrerqErnqre(VachgFgernzErnqre(Flfgrz.va))
    rapvcure(eqe)
    raq
pngpu rk = VBRkprcgvba
  rk.cevagFgnpxGenpr
raq

erghea

zrgubq rapvcure(eqe = OhssrerqErnqre) choyvp fgngvp fvtanyf VBRkprcgvba

  ybbc ynory y_ sberire
    yvar = eqe.ernqYvar
    vs yvar = ahyy gura yrnir y_
    fnl ebg13(yvar)
    raq y_
  erghea

zrgubq ebg13(vachg) choyvp fgngvp fvtanyf VyyrtnyNethzragRkprcgvba

  erghea pnrfne(vachg, 13, vfSnyfr)

zrgubq pnrfne(vachg = Erkk, vqk = vag, pncf = obbyrna) choyvp fgngvp fvtanyf VyyrtnyNethzragRkprcgvba

  vs vqk < 1 | vqk > 25 gura fvtany VyyrtnyNethzragRkprcgvba()

  --      12345678901234567890123456
  vgno = 'NOPQRSTUVWXYZABCDEFGHIJKLM'
  fuvsg = vgno.yratgu - vqk
  cnefr vgno gy +(fuvsg) ge
  bgno = ge || gy

  vs pncf gura vachg = vachg.hccre

  pvcure = vachg.genafyngr(vgno || vgno.ybjre, bgno || bgno.ybjre)

  erghea pvcure

zrgubq pnrfne_rapvcure(vachg = Erkk, vqk = vag, pncf = obbyrna) choyvp fgngvp fvtanyf VyyrtnyNethzragRkprcgvba

  erghea pnrfne(vachg, vqk, pncf)

zrgubq pnrfne_qrpvcure(vachg = Erkk, vqk = vag, pncf = obbyrna) choyvp fgngvp fvtanyf VyyrtnyNethzragRkprcgvba

  erghea pnrfne(vachg, vag(26) - vqk, vfSnyfr)

zrgubq pnrfne_rapvcure(vachg = Erkk, vqk = vag) choyvp fgngvp fvtanyf VyyrtnyNethzragRkprcgvba

  erghea pnrfne(vachg, vqk, vfSnyfr)

zrgubq pnrfne_qrpvcure(vachg = Erkk, vqk = vag) choyvp fgngvp fvtanyf VyyrtnyNethzragRkprcgvba

  erghea pnrfne(vachg, vag(26) - vqk, vfSnyfr)

zrgubq pnrfne_rapvcure(vachg = Erkk, vqk = vag, bcg = Erkk) choyvp fgngvp fvtanyf VyyrtnyNethzragRkprcgvba

  erghea pnrfne(vachg, vqk, bcg)

zrgubq pnrfne_qrpvcure(vachg = Erkk, vqk = vag, bcg = Erkk) choyvp fgngvp fvtanyf VyyrtnyNethzragRkprcgvba

  erghea pnrfne(vachg, vag(26) - vqk, bcg)

zrgubq pnrfne(vachg = Erkk, vqk = vag, bcg = Erkk) choyvp fgngvp fvtanyf VyyrtnyNethzragRkprcgvba

  vs bcg.hccre.nooeri('H') >= 1 gura pncf = vfGehr
  ryfr                               pncf = vfSnyfr

  erghea pnrfne(vachg, vqk, pncf)

zrgubq pnrfne(vachg = Erkk, vqk = vag) choyvp fgngvp fvtanyf VyyrtnyNethzragRkprcgvba

  erghea pnrfne(vachg, vqk, vfSnyfr)

zrgubq vfGehr choyvp fgngvp ergheaf obbyrna
  erghea (1 == 1)

zrgubq vfSnyfr choyvp fgngvp ergheaf obbyrna
  erghea \vfGehr

Objeck

<lang objeck> bundle Default {

 class Rot13 {
   function : Main(args : String[]) ~ Nil {
     Rot13("nowhere ABJURER")->PrintLine();
   }
   function : native : Rot13(text : String) ~ String {
     rot := "";
     each(i : text) {
       c := text->Get(i);
       if(c >= 'a' & c <= 'm' | c >= 'A' & c <= 'M') {
         rot->Append(c + 13);
       }
       else if(c >= 'n' & c <= 'z' | c >= 'N' & c <= 'Z') {
         rot->Append(c - 13);
       }
       else {
         rot->Append(c);
       };
     };
     return rot;
   }
 }

} </lang>

OCaml

Straightforward implementation for characters by using character range patterns:

<lang 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</lang>

We provide a function for converting whole strings:

<lang 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

(* or in OCaml 4.00+:

  let rot13_str = String.map rot13
  • )</lang>

And here is a utility program that converts the content read on sdtin and write it to stdout:

<lang ocaml>let () =

 try while true do
   String.iter (fun c -> print_char (rot13 c)) (read_line());
   print_newline()
 done with End_of_file -> ()</lang>

Oz

<lang oz>declare

 fun {RotChar C}
    if     C >= &A andthen C =< &Z then &A + (C - &A + 13) mod 26
    elseif C >= &a andthen C =< &z then &a + (C - &a + 13) mod 26
    else C
    end
 end
 fun {Rot13 S}
    {Map S RotChar}
 end

in

 {System.showInfo {Rot13 "NOWHERE Abjurer 42"}}
 {System.showInfo {Rot13 {Rot13 "NOWHERE Abjurer 42"}}}</lang>

PARI/GP

<lang parigp>rot13(s)={

 s=Vecsmall(s);
 for(i=1,#s,
   if(s[i]>109&s[i]<123,s[i]-=13,if(s[i]<110&s[i]>96,s[i]+=13,if(s[i]>77&s[i]<91,s[i]-=13,if(s[i]<78&s[i]>64,s[i]+=13))))
 );
 Strchr(s)

};</lang>

Pascal

<lang Pascal>program rot13(input, output);

function rot13(someText: string): string; var

 i: integer;
 ch: char;
 resultText: string = ;

begin

 for i := 1 to Length(someText) do begin
   ch := someText[i];
   case ch  of
     'A' .. 'M', 'a' .. 'm': ch := chr(ord(ch)+13);
     'N' .. 'Z', 'n' .. 'z': ch := chr(ord(ch)-13)
   end;
   resultText := resultText + ch
 end;
 rot13 := resultText

end;

var

 line: string;

begin

 while not eof(input) do begin
   readln(line);
   writeln(rot13(line))
 end

end.</lang>


Perl

<lang perl>sub rot13 {

 my $string = shift;
 $string =~ tr/A-Za-z/N-ZA-Mn-za-m/;
 return $string;

}

print rot13($_) while (<>);</lang>

Input:

NOWHERE Abjurer

Output:

ABJURER Nowhere

This one-liner version demonstrates that most of the verbosity above was simply needed to define a function:

<lang perl>perl -pe 'tr/A-Za-z/N-ZA-Mn-za-m/'</lang>

Perl 6

Works with: Rakudo Star version 2013.07

<lang perl6>sub rot13 { $^s.trans: 'a..mn..z' => 'n..za..m', :ii }

multi MAIN () { print rot13 slurp } multi MAIN (*@files) { print rot13 [~] map &slurp, @files }</lang>

This illustrates use of multi-dispatch to MAIN based on number of arguments.

PHP

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

sbb

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

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

}

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

Output:

sbb

PicoLisp

<lang PicoLisp>(de rot13-Ch (C)

  (if
     (or
        (member C '`(apply circ (chop "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))) 
        (member C '`(apply circ (chop "abcdefghijklmnopqrstuvwxyz"))) )
     (get @ 14)
     C ) )</lang>

or: <lang PicoLisp>(de rot13-Ch (C)

  (cond
     ((>= "M" (uppc C) "A")
        (char (+ (char C) 13)) ) 
     ((>= "Z" (uppc C) "N")
        (char (- (char C) 13)) ) 
     (T C) ) )</lang>

Then call it as: <lang PicoLisp>(de rot13-stdIn ()

  (while (line)
     (prinl (mapcar rot13-Ch @)) ) )</lang>

Pike

<lang pike> import Crypto;

int main(){

  string r = rot13("Hello, World");
  write(r + "\n");

} </lang>

PL/I

<lang pli> rotate: procedure (in) options (main); /* 2 March 2011 */

  declare in character (100) varying;
  declare line character (500) varying;
  declare input file;
  open file (input) title ('/' || in || ',type(text),recsize(500)' );
  on endfile (input) stop;
  do forever;
     get file (input) edit (line) (L);
     line = translate (
            line, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
                  'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm');
     put edit (line) (a); put skip;
  end;

end; </lang> Data file:

"The time has come,"
the walrus said,
"to speak of many things;
of ships and shoes and sealing wax;
of cabbages and kings."

Output:

"Gur gvzr unf pbzr,"
gur jnyehf fnvq,
"gb fcrnx bs znal guvatf;
bs fuvcf naq fubrf naq frnyvat jnk;
bs pnoontrf naq xvatf."

PostScript

Library: initlib

<lang postscript> /r13 { 4 dict begin

   /rotc {
       {
       {{{64 gt} {91 lt}} all?} {65 - 13 + 26 mod 65 +} is?
       {{{95 gt} {123 lt}} all?} {97 - 13 + 26 mod 97 +} is?
       } cond
   }.
   {rotc} map cvstr

end}. </lang>

Pop11

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

<lang pop11>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') =></lang>

PowerShell

<lang powershell> Function ROT13($String) {

   $Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
   $Cipher = "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"
   Foreach($Char in $String.ToCharArray())
   {
       If ( $Char -match "[A-Za-z]" )
       { $NewString += $Cipher.Chars($Alphabet.IndexOf($Char)) }
       else
       { $NewString += $Char }
   } 
   Return $NewString

} </lang>

Prolog

Works with SWI-Prolog. <lang Prolog>rot13(Str, SR) :- maplist(rot, Str, Str1), string_to_list(SR, Str1).

rot(C, C1) :- ( member(C, "abcdefghijklmABCDEFGHIJKLM") -> C1 is C+13; ( member(C, "nopqrstuvwxyzNOPQRSTUVWXYZ") -> C1 is C-13; C1 = C)). </lang> Output : <lang Prolog> ?- rot13("The Quick Brown Fox Jumped Over The Lazy Dog!", SR). SR = "Gur Dhvpx Oebja Sbk Whzcrq Bire Gur Ynml Qbt!".</lang>

PureBasic

<lang PureBasic>Declare.s Rot13(text_to_code.s)

If OpenConsole()

 Define txt$
 
 Print("Enter a string to encode: "): txt$=Input()

 PrintN("Coded  : "+Rot13(txt$))
 PrintN("Decoded: "+Rot13(Rot13(txt$)))

 Print("Press ENTER to quit."): Input()
 CloseConsole()

EndIf

Procedure.s Rot13(s.s)

 Protected.i i
 Protected.s t, u
 For i=1 To Len(s)
   t=Mid(s,i,1)
   Select Asc(t)
     Case Asc("a") To Asc("m"), Asc("A") To Asc("M")
       t=chr(Asc(t)+13)
     Case Asc("n") To Asc("z"), Asc("N") To Asc("Z")
       t=chr(Asc(t)-13)
   EndSelect
   u+t
 Next  
 ProcedureReturn u

EndProcedure</lang>

Python

Python 2.x (but not 3.x) has built-in rot13 encoding and decoding:

Works with: Python version 2.x
>>> u'foo'.encode('rot13')
'sbb'
>>> 'sbb'.decode('rot13')
u'foo'

Here is an implementation:

Works with: Python version 2.x

<lang 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 s.translate(
      string.maketrans(
          string.ascii_uppercase + string.ascii_lowercase,
          string.ascii_uppercase[13:] + string.ascii_uppercase[:13] +
          string.ascii_lowercase[13:] + string.ascii_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)!</lang>

The str.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).

Works with: Python version 3.x

In Python 3.x, the string.maketrans() function actually only works for the bytes type, and has been deprecated since 3.1. If you want to work on strings (str type), you need to use str.maketrans(): <lang 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 s.translate(
      str.maketrans(
          string.ascii_uppercase + string.ascii_lowercase,
          string.ascii_uppercase[13:] + string.ascii_uppercase[:13] +
          string.ascii_lowercase[13:] + string.ascii_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), end="")</lang>

R

<lang R>rot13 <- function(x) {

 old <- paste(letters, LETTERS, collapse="", sep="")
 new <- paste(substr(old, 27, 52), substr(old, 1, 26), sep="")
 chartr(old, new, x)

} x <- "The Quick Brown Fox Jumps Over The Lazy Dog!.,:;'#~[]{}" rot13(x) # "Gur Dhvpx Oebja Sbk Whzcf Bire Gur Ynml Qbt!.,:;'#~[]{}" x2 <- paste(letters, LETTERS, collapse="", sep="") rot13(x2) # "nNoOpPqQrRsStTuUvVwWxXyYzZaAbBcCdDeEfFgGhHiIjJkKlLmM"</lang> For a slightly more general function, see the example on the chartr help page.

Racket

<lang racket>

  1. !/bin/env racket
  2. lang racket/base

(define (run i o)

 (for ([ch (in-producer regexp-match #f #rx#"[a-zA-Z]" i 0 #f o)])
   (define b (bytes-ref (car ch) 0))
   (define a (if (< b 96) 65 97))
   (write-byte (+ (modulo (+ 13 (- b a)) 26) a))))

(require racket/cmdline) (command-line

#:help-labels "(\"-\" specifies standard input)"
#:args files
(for ([f (if (null? files) '("-") files)])
  (if (equal? f "-")
    (run (current-input-port) (current-output-port))
    (call-with-input-file f (λ(i) (run i (current-output-port)))))))

</lang>

Raven

<lang Raven>define rot13 use $str

   $str each chr
       dup m/[A-Ma-m]/ if
           ord 13 + chr
       else
           dup m/[N-Zn-z]/ if
              ord 13 - chr
   $str length list "" join

"12!ABJURER nowhere" dup print "\nas rot13 is\n" print rot13 print "\n" print</lang>

Output:
12!ABJURER nowhere
as rot13 is
12!NOWHERE abjurer

REBOL

<lang REBOL>REBOL [

   Title: "Rot-13"
   Date: 2009-12-14
   Author: oofoe
   URL: http://rosettacode.org/wiki/Rot-13

]

Test data has upper and lower case characters as well as characters
that should not be transformed, like numbers, spaces and symbols.

text: "This is a 28-character test!"

print "Using cipher table:"

I build a set of correspondence lists here. 'x' is the letters from
A-Z, in both upper and lowercase form. Note that REBOL can iterate
directly over the alphabetic character sequence in the for loop. 'y'
is the cipher form, 'x' rotated by 26 characters (remember, I have
the lower and uppercase forms together). 'r' holds the final result,
built as I iterate across the 'text' string. I search for the
current character in the plaintext list ('x'), if I find it, I get
the corresponding character from the ciphertext list
('y'). Otherwise, I pass the character through untransformed, then
return the final string.

rot-13: func [ "Encrypt or decrypt rot-13 with tables." text [string!] "Text to en/decrypt." /local x y r i c ] [ x: copy "" for i #"a" #"z" 1 [append x rejoin [i uppercase i]] y: rejoin [copy skip x 26 copy/part x 26] r: copy ""

repeat i text [append r either c: find/case x i [y/(index? c)][i]] r ]

Note that I am setting the 'text' variable to the result of rot-13
so I can reuse it again on the next call. The rot-13 algorithm is
reversible, so I can just run it again without modification to decrypt.

print [" Encrypted:" text: rot-13 text] print [" Decrypted:" text: rot-13 text]


print "Using parse:"

clamp: func [ "Contain a value within two enclosing values. Wraps if necessary." x v y ][ x: to-integer x v: to-integer v y: to-integer y case [v < x [y - v] v > y [v - y + x - 1] true v] ]

I'm using REBOL's 'parse' word here. I set up character sets for
upper and lower-case letters, then let parse walk across the
text. It looks for matches to upper-case letters, then lower-case,
then skips to the next one if it can't find either. If a matching
character is found, it's mathematically incremented by 13 and
clamped to the appropriate character range. parse changes the
character in place in the string, hence this is a destructive
operation.

rot-13: func [ "Encrypt or decrypt rot-13 with parse." text [string!] "Text to en/decrypt. Note: Destructive!" ] [ u: charset [#"A" - #"Z"] l: charset [#"a" - #"z"]

parse text [some [ i:  ; Current position. u (i/1: to-char clamp #"A" i/1 + 13 #"Z") | ; Upper case. l (i/1: to-char clamp #"a" i/1 + 13 #"z") | ; Lower case. skip]]  ; Ignore others. text ]

As you see, I don't need to re-assign 'text' anymore.

print [" Encrypted:" rot-13 text] print [" Decrypted:" rot-13 text] </lang>

Output:

Using cipher table:
    Encrypted: Guvf vf n 28-punenpgre grfg!
    Decrypted: This is a 28-character test!
Using parse:
    Encrypted: Guvf vf n 28-punenpgre grfg!
    Decrypted: This is a 28-character test!

Retro

<lang retro>{{

 : rotate  ( cb-c ) tuck - 13 + 26 mod + ;
 : rotate? (  c-c )
   dup 'a 'z within [ 'a rotate ] ifTrue
   dup 'A 'Z within [ 'A rotate ] ifTrue ;

---reveal---

 : rot13   (  s-s ) dup [ [ @ rotate? ] sip ! ] ^types'STRING each@ ;

}}

"abcdef123GHIJKL" rot13 dup puts cr rot13 puts "abjurer NOWHERE" rot13 puts</lang>

REXX

<lang rexx>/*REXX program to encode several text strings with ROT 13 algorithm. */ aa = 'foo' say 'simple text = 'aa say ' rot13 text = 'rot13(aa) say

bb = 'bar' say 'simple text = 'bb say ' rot13 text = 'rot13(bb) say

cc = "Noyr jnf V, 'rer V fnj Ryon." say 'simple text = 'cc say ' rot13 text = 'rot13(cc) say

dd = 'abc? ABC!' say 'simple text = 'dd say ' rot13 text = 'rot13(dd) say

ee = 'abjurer NOWHERE' say 'simple text = 'ee say ' rot13 text = 'rot13(ee) exit /*stick a fork in it, we're done.*/

/*──────────────────────────────────ROT13 subroutine────────────────────*/ rot13: return translate(arg(1),,

 'abcdefghijklmABCDEFGHIJKLMnopqrstuvwxyzNOPQRSTUVWXYZ',,
 'nopqrstuvwxyzNOPQRSTUVWXYZabcdefghijklmABCDEFGHIJKLM')</lang>

output

simple text = foo
 rot13 text = sbb

simple text = bar
 rot13 text = one

simple text = Noyr jnf V, 'rer V fnj Ryon.
 rot13 text = Able was I, 'ere I saw Elba.

simple text = abc?  ABC!
 rot13 text = nop?  NOP!

simple text = abjurer NOWHERE
 rot13 text = nowhere ABJURER

Ruby

<lang ruby># Returns a copy of _s_ with rot13 encoding. def rot13(s)

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

end

  1. Perform rot13 on files from command line, or standard input.

while line = ARGF.gets

 print rot13(line)

end</lang>

One can run ruby rot13.rb file1 file2 to rot13 those files, or run ruby rot13.rb to rot13 the standard input.

Input:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Output:

NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm

Run BASIC

<lang runbasic>INPUT "Enter a string: "; s$ ans$ = "" FOR a = 1 TO LEN(s$)

       letter$ = MID$(s$, a, 1)
       IF letter$ >= "A" AND letter$ <= "Z" THEN
          char$ = CHR$(ASC(letter$) + 13)
          IF char$ > "Z" THEN char$ = CHR$(ASC(char$) - 26)
       else  
          if 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$</lang>Output:

Enter a string: ?abc
nop
Enter a string: ?ABC 
NOP

Scala

<lang scala>scala> def rot13(s: String) = s map {

    |   case c if 'a' <= c.toLower && c.toLower <= 'm' => c + 13 toChar
    |   case c if 'n' <= c.toLower && c.toLower <= 'z' => c - 13 toChar
    |   case c => c
    | }

rot13: (s: String)String

scala> rot13("7 Cities of Gold.") res61: String = 7 Pvgvrf bs Tbyq.

scala> rot13(res61) res62: String = 7 Cities of Gold.</lang>

Scheme

<lang scheme>(define (rot13 str)

 (define (rot13-char c)
   (integer->char (+ (char->integer c)
                     (cond ((and (char>=? c #\a) (char<? c #\n))
                            13)
                           ((and (char>=? c #\A) (char<? c #\N))
                            13)
                           ((and (char>=? c #\n) (char<=? c #\z))
                            -13)
                           ((and (char>=? c #\N) (char<=? c #\Z))
                            -13)
                           (else
                            0)))))
 (list->string (map rot13-char (string->list str))))

</lang>

sed

The two translations (upper and lower case) are separate only for documentation and ease of understanding; they could be combined into one command. <lang sed>y/abcdefghijklmnopqrstuvwxyz/nopqrstuvwxyzabcdefghijklm/ y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/NOPQRSTUVWXYZABCDEFGHIJKLM/</lang>

Seed7

This rot13 program reads from standard input and writes to standard output: <lang seed7>$ 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;</lang>

Slate

A shell script:

<lang slate>#!/usr/local/bin/slate

ch@(String Character traits) rot13 [| value |

 upper ::= ch isUppercase.
 value := ch toLowercase as: Integer.
 (value >= 97) /\ [value < 110]
   ifTrue: [value += 13]
   ifFalse: [(value > 109) /\ [value <= 122]
               ifTrue: [value -= 13]].
 upper
   ifTrue: [(value as: String Character) toUppercase]
   ifFalse: [value as: String Character]

].

lobby define: #Rot13Encoder &parents: {Encoder}.

c@(Rot13Encoder traits) convert [

 [c in isAtEnd] whileFalse: [c out nextPut: c in next rot13].

].

(Rot13Encoder newFrom: Console reader to: Console writer) convert.</lang>

Normal functions:

<lang slate>ch@(String Character traits) rot13 [| value |

 upper ::= ch isUppercase.
 value := ch toLowercase as: Integer.
 (value >= 97) /\ [value < 110]
   ifTrue: [value += 13]
   ifFalse: [(value > 109) /\ [value <= 122]
               ifTrue: [value -= 13]].
 upper
   ifTrue: [(value as: String Character) toUppercase]
   ifFalse: [value as: String Character]

].

s@(String traits) rot13 [

 result ::= s newSameSize.
 s doWithIndex: [| :each :index | result at: index put: each rot13].
 result

].

slate[37]> 'abc123' rot13. 'nop123'</lang>

Smalltalk

Works with: GNU Smalltalk

Here we implemented three ways. The first one is the simplest. The second demonstrates extending the String class with a generic rot method, which in turn uses two new method for the class Character (+ and -). The third one is an imitation of the tr '[a-m][n-z]' '[n-z][a-m]' approach (see UNIX Shell example), done through a block closure and using also the new method trFrom:to: for Character.

<lang smalltalk>"1. simple approach" rot13 := [ :string |

 string collect: [ :each | | index |
   index := 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 
     indexOf: each ifAbsent: [ 0 ]. "Smalltalk uses 1-based indexing" 
       index isZero
         ifTrue: [ each ]
         ifFalse: [ 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM' at:
           index ] ] ].

(rot13 value: 'Test123') printNl "gives 'Grfg123'"

"2. extending built-in classes" Character extend [

 + inc [
    (inc isKindOf: Character)
    ifTrue: [
       ^ ( Character value: ((self asInteger) + (inc asInteger)) )
    ] ifFalse: [
      ^ ( Character value: ((self asInteger) + inc) )
    ]
 ]
 - inc [
   ^ ( self + (inc asInteger negated) )
 ]
 trFrom: map1 to: map2 [
    (map1 includes: self) ifTrue: [
       ^ map2 at: (map1 indexOf: self)
    ] ifFalse: [ ^self ]
 ]

].

String extend [

 rot: num [ |s|
   s := String new.
   self do: [ :c |
        ((c asLowercase) between: $a and: $z)

ifTrue: [ |c1|

             c1 := ( $a + ((((c asLowercase) - $a + num) asInteger) rem:26)).
             (c isLowercase) ifFalse: [ c1 := c1 asUppercase ].
             s := s, (c1 asString)
          ]
          ifFalse: [

s := s, (c asString)

          ]
    ].
    ^s
 ]

].

('abcdefghijklmnopqrstuvwxyz123!' rot: 13) displayNl. (('abcdefghijklmnopqrstuvwxyz123!' rot: 13) rot: 13) displayNl.


"2. using a 'translation'. Not very idiomatic Smalltalk code" rotThirteen := [ :s | |m1 m2 r|

 r := String new.
 m1 := OrderedCollection new.
 0 to: 25 do: [ :i | m1 add: ($a + i) ].
 m2 := OrderedCollection new.
 0 to: 25 do: [ :i | m2 add: ($a + ((i+13) rem: 26)) ].
 s do: [ :c |
   (c between: $a and: $z) | (c between: $A and: $Z)
     ifTrue: [ | a |
       a := (c asLowercase) trFrom: m1 to: m2.
       (c isUppercase) ifTrue: [ a := a asUppercase ].
       r := r, (a asString)] 
     ifFalse: [ r := r, (c asString) ]
 ].
 r

].

(rotThirteen value: 'abcdefghijklmnopqrstuvwxyz123!') displayNl.</lang>

SNOBOL4

Works with: Macro Spitbol
Works with: Snobol4+
Works with: CSnobol

<lang SNOBOL4>* # Function using replace( )

       define('rot13(s)u1,u2,l1,l2') :(rot13_end)

rot13 &ucase len(13) . u1 rem . u2

       &lcase len(13) . l1 rem . l2
       rot13 = replace(s,&ucase &lcase,u2 u1 l2 l1) :(return)

rot13_end

  • # Function using pattern
       define('rot13s(s)c')
       alfa = &ucase &ucase &lcase &lcase :(rot13s_end)

rot13s s len(1) . c = :f(return)

       alfa break(c) len(13) len(1) . c
       rot13s = rot13s c :(rot13s)

rot13s_end

  • # Test and display both
       str = rot13("I abjure the $19.99 trinket!")
       output = str; output = rot13(str)
       str = rot13s("He's a real Nowhere Man.")
       output = str; output = rot13s(str)

end</lang>

Output:

V nowher gur $19.99 gevaxrg!
I abjure the $19.99 trinket!
Ur'f n erny Abjurer Zna.
He's a real Nowhere Man.

Standard ML

<lang sml>fun rot13char c =

 if c >= #"a" andalso c <= #"m" orelse c >= #"A" andalso c <= #"M" then
   chr (ord c + 13)
 else if c >= #"n" andalso c <= #"z" orelse c >= #"N" andalso c <= #"Z" then
   chr (ord c - 13)
 else
   c

val rot13 = String.map rot13char</lang>

SQL

Works with: T-SQL

<lang tsql> with cte(num) as (

select 1
union all
select num+1
from cte

) select cast(( select char(ascii(chr) + case when ascii(chr) between ascii('a') and ascii('m') or ascii(chr) between ascii('A') and ascii('M') then 13 when ascii(chr) between ascii('n') and ascii('z') or ascii(chr) between ascii('N') and ascii('Z') then -13 else 0 end) from ( select top(1000) num, -- your string to be converted to ROT13

                substring('The Quick Brown Fox Jumps Over The Lazy Dog',num,1) chr

from cte ) tmp For XML PATH ()) as xml).value('.', 'VARCHAR(max)') rot13 option (maxrecursion 0) </lang>

Tcl

<lang tcl>proc rot13 line {

   string map {
       a n b o c p d q e r f s g t h u i v j w k x l y m z
       n a o b p c q d r e s f t g u h v i w j x k y l z m
       A N B O C P D Q E R F S G T H U I V J W K X L Y M Z
       N A O B P C Q D R E S F T G U H V I W J X K Y L Z M
   } $line

}</lang>

Using

Library: TclX

we can write

<lang tcl>package require Tclx proc rot13 str {

   translit "A-Za-z" "N-ZA-Mn-za-m" $str

}</lang>

TorqueScript

--Ipquarx 8:45 PM <lang Torque>function rot13(%string) { %alph = "abcdefghijklmnopqrstuvwxyz"; %len = strLen(%string);

for(%a = 0; %a < %len; %a++) { %char = getSubStr(%string,%a,1); %pos = striPos(%alph, %char);

if(%pos < 0) %out = %out @ %char; else { if(strPos(%alph, %char) < 0) %out = %out @ strUpr(getSubStr(%alph, (%pos + 13) % 26)); else %out = %out @ getSubStr(%alph, (%pos + 13) % 26); } } return %out; }</lang>

TI-83 BASIC

Calculator symbol translations:

"STO" arrow: →

Perfoms ROT-13 on the contents of Str1. Also uses the string variables Str0 and Str2 and the real variable N.

<lang ti83b>:"ABCDEFGHIJKLMNOPQRSTUVWXYZ→Str0

".→Str2
For(N,1,length(Str1
If inString(Str0,sub(Str1,N,1
Then
inString(Str0,sub(Str1,N,1
Ans+13-26(Ans>13
Str2+sub(Str0,Ans,1→Str2
Else
Str2+sub(Str1,N,1→Str2
End
End
sub(Str2,2,length(Str2)-1→Str1</lang>

TXR

Via definition and subsequent use of a named filter.

<lang txr>@(deffilter rot13

  ("a" "n") ("b" "o") ("c" "p") ("d" "q") ("e" "r") ("f" "s") ("g" "t")
  ("h" "u") ("i" "v") ("j" "w") ("k" "x") ("l" "y") ("m" "z") ("n" "a")
  ("o" "b") ("p" "c") ("q" "d") ("r" "e") ("s" "f") ("t" "g") ("u" "h")
  ("v" "i") ("w" "j") ("x" "k") ("y" "l") ("z" "m")
  ("A" "N") ("B" "O") ("C" "P") ("D" "Q") ("E" "R") ("F" "S") ("G" "T")
  ("H" "U") ("I" "V") ("J" "W") ("K" "X") ("L" "Y") ("M" "Z") ("N" "A")
  ("O" "B") ("P" "C") ("Q" "D") ("R" "E") ("S" "F") ("T" "G") ("U" "H")
  ("V" "I") ("W" "J") ("X" "K") ("Y" "L") ("Z" "M"))

@(collect :vars ()) @line @ (output :filter rot13) @line @ (end) @(end)</lang>

The :vars () argument to collect means that it still iterates, but doesn't actually collect anything (empty list of variables). This is important, so that there isn't a growing data structure being accumulated as the input is processed.

UNIX Shell

Bourne Shell

<lang bash>#!/bin/sh function rot13 () {

  tr '[a-m][n-z][A-M][N-Z]' '[n-z][a-m][N-Z][A-M]'
  }

cat ${1+"$@"} | rot13</lang>

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. A simple tr a-zA-Z n-za-mN-ZA-M would work with modern systems that follow POSIX. Our tr '[a-m][n-z][A-M][N-Z]' '[n-z][a-m][N-Z][A-M]' also works with those older System V systems. For newer systems, it translates '[' and ']' to themselves. (Refer to OpenBSD tr(1) manual page, section STANDARDS.)

This example shows proper quoting around "$@" (magical argument list) such that this script work properly even if some of the files named on the command line contain embedded spaces or other such characters. (The ${1+"$@"} check, unnecessary in modern systems, allows the script to work even on older systems where a bare "$@" expanded to a single empty string when no arguments were supplied).

Unlambda

<lang Unlambda>``ci`d``@i`c``s`d```?aic.n``s`d```?bic.o``s`d```?cic.p``s`d```?dic.q``s`d```?eic .r``s`d```?fic.s``s`d```?gic.t``s`d```?hic.u``s`d```?iic.v``s`d```?jic.w``s`d``` ?kic.x``s`d```?lic.y``s`d```?mic.z``s`d```?nic.a``s`d```?oic.b``s`d```?pic.c``s` d```?qic.d``s`d```?ric.e``s`d```?sic.f``s`d```?tic.g``s`d```?uic.h``s`d```?vic.i ``s`d```?wic.j``s`d```?xic.k``s`d```?yic.l``s`d```?zic.m``s`d```?Nic.A``s`d```?O ic.B``s`d```?Pic.C``s`d```?Qic.D``s`d```?Ric.E``s`d```?Sic.F``s`d```?Tic.G``s`d` ``?Uic.H``s`d```?Vic.I``s`d```?Wic.J``s`d```?Xic.K``s`d```?Yic.L``s`d```?Zic.M`` s`d```?Aic.N``s`d```?Bic.O``s`d```?Cic.P``s`d```?Dic.Q``s`d```?Eic.R``s`d```?Fic .S``s`d```?Gic.T``s`d```?Hic.U``s`d```?Iic.V``s`d```?Jic.W``s`d```?Kic.X``s`d``` ?Lic.Y``s`d```?Mic.Z`d`|c</lang>

Ursala

I/O in Ursala is meant to be handled automatically as much as possible by the run time system. This source text describes only a function that operates on the contents of a list of files passed to it as an argument, with the transformed files returned as a result. The #executable compiler directive and its parameters mean that this source will be compiled to an executable file with the required command line interface. The rot13 encryption algorithm itself is a simple finite map implemented in a half line of code. <lang Ursala>#import std

  1. executable (<'parameterized','default-to-stdin'>,<>)

rot = ~command.files; * contents:= ~contents; * * -:~& -- ^p(~&,rep13~&zyC)~~ ~=`A-~ letters</lang>

Vedit macro language

Using ROT13.TBL from here <lang vedit>Translate_Load("ROT13.TBL") Translate_Block(0, File_Size)</lang>

You can execute the macro from DOS command prompt with the following command:

vpw -q -x rot13.vdm inputfile -a outputfile

In addition to translating a block of text, the translate table allows viewing and editing ROT-13 text without translating the actual file into ASCII. The displayed characters and keyboard input are translated on-the-fly. This is the normal way to edit for example DOS/OEM and EBCDIC files.

Visual Basic .NET

Platform: .NET

Works with: Visual Basic .NET version 9.0+

<lang vbnet>Module Module1

  Private Function rot13(ByVal str As String) As String
      Dim newChars As Char(), i, j As Integer, original, replacement As String
      original = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
      replacement = "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"
      newChars = str.ToCharArray()
      For i = 0 To newChars.Length - 1
          For j = 0 To 51
              If newChars(i) = original(j) Then
                  newChars(i) = replacement(j)
                  Exit For
              End If
          Next
      Next
      Return New String(newChars)
  End Function

End Module</lang> This solution just uses simple textual substitution, since the number of characters involved is small. If the cipher involved more characters, it would be better to use character arithmetic; however, this is not encouraged in VB.Net.

Wart

<lang python>def (rot13 s)

 (as string
     (map rot13
          (as list s)))

Alphabet <- "abcdefghijklmnopqrstuvwxyz" def (rot13 c) :case (and string?.c len.c=1)

 if ("a" <= c <= "z")
      let idx (pos c Alphabet)
        Alphabet (idx+13 % 26)
    ("A" <= c <= "Z")
      (downcase.c -> rot13 -> upcase)
    :else
      c</lang>

Output: <lang python>(rot13 "Moron") => "Zbeba"</lang>

X86 Assembly

Using Linux/FASM. <lang asm>format ELF executable 3 entry start

segment readable writeable buf rb 1

segment readable executable start: mov eax, 3 ; syscall "read" mov ebx, 0 ; stdin mov ecx, buf ; buffer for read byte mov edx, 1 ; len (read one byte) int 80h

cmp eax, 0 ; EOF? jz exit

xor eax, eax ; load read char to eax mov al, [buf] cmp eax, "A" ; see if it is in ascii a-z or A-Z jl print cmp eax, "z" jg print cmp eax, "Z" jle rotup cmp eax, "a" jge rotlow jmp print

rotup: sub eax, "A"-13 ; do rot 13 for A-Z cdq mov ebx, 26 div ebx add edx, "A" jmp rotend

rotlow: sub eax, "a"-13 ; do rot 13 for a-z cdq mov ebx, 26 div ebx add edx, "a"

rotend: mov [buf], dl

print: mov eax, 4 ; syscall write mov ebx, 1 ; stdout mov ecx, buf ; *char mov edx, 1 ; string length int 80h

jmp start

exit: mov eax,1 ; syscall exit xor ebx,ebx ; exit code int 80h</lang>

XPL0

Usage: rot13 <infile.txt >outfile.txt <lang XPL0>code ChIn=7, ChOut=8; int C, CC; repeat C:= ChIn(1); CC:= C&~$20; \CC handles lowercase too

       ChOut(0, C + (if CC>=^A & CC<=^M then +13
                else if CC>=^N & CC<=^Z then -13
                else 0));

until C = $1A; \EOF</lang>

XSLT

Textual transforms are one of the domains XSLT was designed for. <lang xml><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></lang> 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.

ZX Spectrum Basic

Translation of: QBasic

<lang zxbasic>10 CLS 20 INPUT "Enter a string: ", s$ 30 LET a$ = "": REM a$ is the encoded string 40 FOR l = 1 TO LEN(s$) 50 LET i$ = s$(l): REM i$ is the letter being worked on 60 IF i$ < "A" OR i$ > "Z" THEN GO TO 100 70 LET c$ = CHR$(CODE(i$) + 13): REM c$ is the encoded letter 80 IF c$ > "Z" THEN LET c$ = CHR$(CODE(c$) - 26) 90 GO TO 300 100 IF i$ < "a" OR i$ > "z" THEN GO TO 200 110 LET c$ = CHR$(CODE(i$) + 13) 120 IF c$ > "z" THEN LET c$ = CHR$(CODE(c$) - 26) 130 GO TO 300 200 LET c$ = i$ 300 LET a$ = a$ + c$ 310 NEXT l 320 PRINT a$</lang>