Rot-13

From Rosetta Code
Jump to: navigation, search
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.

Contents

[edit] 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.

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

[edit] ACL2

(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))

[edit] 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;

[edit] 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
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 #

Sample run on linux:

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

[edit] AppleScript

Using do shell script

to rot13(textString)
do shell script "tr a-zA-Z n-za-mN-ZA-M <<<" & quoted form of textString
end rot13

Pure AppleScript solution

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
 

Demo code:

rot13("nowhere ABJURER")

Output:

abjurer NOWHERE

[edit] AutoHotkey

Simple alphabet remapping method by Raccoon. Similar to a translate() function in many languages.

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
}

Simple ASCII math method by Raccoon. Add or subtract 13 depending on the character's decimal value.

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
}

Code modified from stringmod by Hugo: ahk discussion

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
}

from LinearSpoon's Translation of The Worlds Shortest C Implementation of Rot13

Rot13(string) {
Output := ""
Loop, Parse, string
{
a := ~Asc(A_LoopField)
Output .= Chr(~a-1//(~(a|32)//13*2-11)*13)
}
return Output
}

[edit] 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
}

[edit] BASIC

Works with: 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$

[edit] Alternate version

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

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$

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

[edit] BBC BASIC

      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$
 

[edit] Befunge

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

[edit] 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"
 

[edit] C

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
 
#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;
}

[edit] Alternative version

This version rot13'd lowercase and uppercase letters.

File can be processing simply by piping:

cat filename | ./rot13
#include <stdio.h>
#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;
}

[edit] C#

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()));
}
}
}

[edit] C++

#include <iostream>
#include <istream>
#include <ostream>
#include <fstream>
#include <cstdlib>
#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;
}

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

Library: Boost
#include <iostream>
#include <string>
#include <boost/iostreams/concepts.hpp> // output_filter
#include <boost/iostreams/operations.hpp> // put
#include <boost/iostreams/filtering_stream.hpp>
#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();
}
}
 
 

[edit] C++11

#include <string>
#include <iostream>
#include <fstream>
 
char rot13(char c){
if (c >= 'a' && c <= 'z')
return (c - 'a' + 13) % 26 + 'a';
else if (c >= 'A' && c <= 'Z')
return (c - 'A' + 13) % 26 + 'A';
return c;
}
 
std::string &rot13(std::string &s){
for (auto &c : s) //range based for is the only used C++11 feature
c = rot13(c);
return s;
}
 
void rot13(std::istream &in, std::ostream &out){
std::string s;
while (std::getline(in, s))
out << rot13(s) << '\n';
}
 
int main(int argc, char *argv[]){
if (argc == 1)
rot13(std::cin, std::cout);
for (int arg = 1; arg < argc; ++arg){
std::ifstream f(argv[arg]);
if (!f)
return EXIT_FAILURE;
rot13(f, std::cout);
}
}

[edit] Clojure

All invocations produce "Gur Dhvpx Oebja Sbk Whzcrq Bire Gur Ynml Qbt!"

(ns rosettacode.rot-13)
 
(let [a (int \a) m (int \m) A (int \A) M (int \M)
n (int \n) z (int \z) N (int \N) Z (int \Z)]
(defn rot-13 [^Character c]
(char (let [i (int c)]
(cond-> i
(or (<= a i m) (<= A i M)) (+ 13)
(or (<= n i z) (<= N i Z)) (- 13))))))
 
(apply str (map rot-13 "The Quick Brown Fox Jumped Over The Lazy Dog!"))
 
; An alternative implementation using a map:
(let [A (into #{} "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
Am (->> (cycle A) (drop 26) (take 52) (zipmap A))]
(defn rot13 [^String in]
(apply str (map #(Am % %) in))))
 
(rot13 "The Quick Brown Fox Jumped Over The Lazy Dog!")

[edit] 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
.

[edit] Common Lisp

The standard gives implementations great leeway with respect to character encodings, so we can't rely on the convenient properties of ASCII.

(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))

[edit] Assuming ASCII Character Set

Though the standard intentionally doesn't specify encoding, every popular implementation today uses ASCII.

(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"

[edit] 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
]

Usage:

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

[edit] D

[edit] Using Standard Functions

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));
}
Output:
The Quick Brown Fox Jumps Over The Lazy Dog!

[edit] Imperative Implementation

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();
}

[edit] Déjà Vu

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."
Output:
Fancr xvyyf Sebqb jvgu Ebfrohq.

[edit] 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 }) }
}

[edit] 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).

[edit] Euphoria

Works with: Euphoria version 4.0.0
 
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" )
 

[edit] 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.

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

[edit] 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

[edit] FALSE

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

[edit] 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)}")
}
}
}
 

[edit] 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.

#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
 

[edit] 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

[edit] Fortran

Works with: Fortran version 90 and later
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

Note: iargc and getarg are common extensions that are implemented by e.g. the Intel Fortran Compiler, G95 and gfortran.

Sample usage:

> 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

[edit] FunL

import io.{lines, stdin}
 
def rot13( s ) =
buf = StringBuilder()
 
for c <- s
if isalpha( c )
n = ((ord(c) and 0x1F) - 1 + 13)%26 + 1
 
buf.append( chr(n or (if isupper(c) then 64 else 96)) )
else
buf.append( c )
 
buf.toString()
 
def rot13lines( ls ) =
for l <- ls
println( rot13(l) )
 
if _name_ == '-main-'
if args.isEmpty()
rot13lines( stdin() )
else
for f <- args
rot13lines( lines(f) )

[edit] 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";
# "England expects that every man will do his duty"
b := rot13(a);
# "Ratynaq rkcrpgf gung rirel zna jvyy qb uvf qhgl"
c := rot13(b);
# "England expects that every man will do his duty"

[edit] Gema

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

[edit] 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;

The above code is called like this:

show_message(rot13("My dog has fleas!"));

Output (in a message box):

Zl qbt unf syrnf!

[edit] 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"))
}

Output:

abjurer NOWHERE

[edit] Groovy

Solution:

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

Test program:

println rot13("Noyr jnf V, 'rer V fnj Ryon.")

Output:

Able was I, 'ere I saw Elba.

[edit] GW-BASIC

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

[edit] Haskell

Straightforward implementation by checking multiple cases:

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

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.

[edit] 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

[edit] Icon and Unicon

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

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

[edit] J

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

For example:

   rot13 'abc! ABC!'
nop! NOP!

Compare with the solution to the Change String Case task.

[edit] 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();
}
}

[edit] 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
 

TDD with Jasmine using Underscore.js

 
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");
});
});
 

[edit] 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...))
Output:
julia> rot13("abcdefghijklmnopqrtuvwxyz 123 ABCDEFGHIJKLMNOPQRTUVWXYZ")
"nopqrstuvwxyzabcdeghijklm 123 NOPQRSTUVWXYZABCDEGHIJKLM"

[edit] K

  rot13: {a:+65 97+\:2 13#!26;_ci@[!256;a;:;|a]_ic x}
 
rot13 "Testing! 1 2 3"
"Grfgvat! 1 2 3"


[edit] 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.
LabVIEW Rot-13.png

[edit] 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
}
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
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')
Output:
NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm

[edit] Liberty BASIC

Liberty BASIC string comparisons are not ascii-based. Verbose version:

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
 

Concise:

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
 

[edit] Limbo

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

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";
}
}
 

[edit] 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


[edit] Locomotive Basic

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

[edit]

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

[edit] Lua

function rot13(s)
local a = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
local b = "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"
return (s:gsub("%a", function(c) return b:sub(a:find(c)) end))
end

[edit] Maple

There is a built-in command for this in Maple.

> StringTools:-Encode( "The Quick Brown Fox Jumped Over The Lazy Dog!", encoding = rot13 ); 
"Gur Dhvpx Oebja Sbk Whzcrq Bire Gur Ynml Qbt!"

[edit] 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]

gives back:

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

[edit] 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

Call it like this:

>> rot13('Hello World!')
 
ans =
 
Uryyb Jbeyq!

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.

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

Sample Output:

>> plainText = char((64:123))
 
plainText =
 
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{
 
>> rot13(plainText)
 
ans =
 
@NOPQRSTUVWXYZABCDEFGHIJKLM[\]^_`nopqrstuvwxyzabcdefghijklm{

[edit] 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"

[edit] 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")

[edit] 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

Example:

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

[edit] Modula-3

This implementation reads from stdin and writes to stdout.

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.

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

[edit] 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

[edit] NetRexx

This sample leverages the code demonstrated in the Caesar cipher – NetRexx task.

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

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

[edit] NewLISP

(define (rot13 str)
(join
(map
(fn(c)
(cond
((<= "A" (upper-case c) "M") (char (+ (char c) 13)))
((<= "N" (upper-case c) "Z") (char (- (char c) 13)))
(true c)))
(explode str))))

[edit] Nimrod

import strutils
 
proc rot13(c): char =
case toLower(c)
of 'a'..'m': chr(ord(c) + 13)
of 'n'..'z': chr(ord(c) - 13)
else: c
 
for line in stdin.lines:
for c in line:
stdout.write rot13(c)
stdout.write "\n"

[edit] 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;
}
}
}
 

[edit] OCaml

Straightforward implementation for characters by using character range patterns:

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

We provide a function for converting whole strings:

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
*)

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

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

[edit] 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"}}}

[edit] PARI/GP

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)
};

[edit] 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.


[edit] Perl

sub rot13 {
shift =~ tr/A-Za-z/N-ZA-Mn-za-m/r;
}
 
print rot13($_) while (<>);

Input:

NOWHERE Abjurer

Output:

ABJURER Nowhere

One-liner version:

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

[edit] Perl 6

Works with: Rakudo Star version 2013.07
sub rot13 { $^s.trans: 'a..mn..z' => 'n..za..m', :ii }
 
multi MAIN () { print rot13 slurp }
multi MAIN (*@files) { print rot13 [~] map &slurp, @files }

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

[edit] PHP

PHP has a built-in function for this:

echo str_rot13('foo'), "\n";

will output

sbb

Here is an implementation:

<?php
function rot13($s) {
return strtr($s, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
'NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm');
}
 
echo rot13('foo'), "\n";
?>

Output:

sbb

[edit] PicoLisp

(de rot13-Ch (C)
(if
(or
(member C '`(apply circ (chop "ABCDEFGHIJKLMNOPQRSTUVWXYZ")))
(member C '`(apply circ (chop "abcdefghijklmnopqrstuvwxyz"))) )
(get @ 14)
C ) )

or:

(de rot13-Ch (C)
(cond
((>= "M" (uppc C) "A")
(char (+ (char C) 13)) )
((>= "Z" (uppc C) "N")
(char (- (char C) 13)) )
(T C) ) )

Then call it as:

(de rot13-stdIn ()
(while (line)
(prinl (mapcar rot13-Ch @)) ) )

[edit] Pike

 
import Crypto;
 
int main(){
string r = rot13("Hello, World");
write(r + "\n");
}
 

[edit] PL/I

 
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;
 

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."

[edit] PostScript

Library: initlib
 
/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}.
 

[edit] 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') =>

[edit] 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
}
 

[edit] Prolog

Works with SWI-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)).
 

Output :

 ?- rot13("The Quick Brown Fox Jumped Over The Lazy Dog!", SR).
SR = "Gur Dhvpx Oebja Sbk Whzcrq Bire Gur Ynml Qbt!".

[edit] 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

[edit] 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'

In both Python 2.x and 3.x one can use the standard library module codecs for rot13 encoding and decoding:

Works with: Python version 2.x
Works with: Python version 3.x
>>> import codecs
>>> codecs.encode("The quick brown fox jumps over the lazy dog", "rot13")
'Gur dhvpx oebja sbk whzcf bire gur ynml qbt'
>>> codecs.decode(_, "rot13")
'The quick brown fox jumps over the lazy dog'

Here is an alternative implementation:

Works with: Python version 2.x
#!/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)!

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():

#!/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="")

[edit] 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"

For a slightly more general function, see the example on the chartr help page.

[edit] Racket

 
#!/bin/env racket
#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)))))))
 

[edit] 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
Output:
12!ABJURER nowhere
as rot13 is
12!NOWHERE abjurer

[edit] 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]

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!

[edit] 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

[edit] REXX

This REXX version supports upper and lower case letters, preserves their case (upper/lower),
and passes all non-alphabetic characters in the input through without alteration.

/*REXX program encodes several text strings with the  ROT-13  algorithm.*/
aa = 'foo'
say 'simple text = 'aa
say 'rot-13 text = 'rot13(aa)
say
bb = 'bar'
say 'simple text = 'bb
say 'rot-13 text = 'rot13(bb)
say
cc = "Noyr jnf V, 'rer V fnj Ryon."
say 'simple text = 'cc
say 'rot-13 text = 'rot13(cc)
say
dd = 'abc? ABC!'
say 'simple text = 'dd
say 'rot-13 text = 'rot13(dd)
say
ee = 'abjurer NOWHERE'
say 'simple text = 'ee
say 'rot-13 text = 'rot13(ee)
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────ROT13 subroutine────────────────────*/
rot13: return translate(arg(1), ,
'abcdefghijklmABCDEFGHIJKLMnopqrstuvwxyzNOPQRSTUVWXYZ', ,
'nopqrstuvwxyzNOPQRSTUVWXYZabcdefghijklmABCDEFGHIJKLM')

output

simple text = foo
rot-13 text = sbb

simple text = bar
rot-13 text = one

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

simple text = abc?  ABC!
rot-13 text = nop?  NOP!

simple text = abjurer NOWHERE
rot-13 text = nowhere ABJURER

[edit] Ruby

# Returns a copy of _s_ with rot13 encoding.
def rot13(s)
s.tr('A-Za-z', 'N-ZA-Mn-za-m')
end
 
# Perform rot13 on files from command line, or standard input.
while line = ARGF.gets
print rot13(line)
end

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

[edit] Run BASIC

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$
Output:
Enter a string: ?abc

nop Enter a string: ?ABC

NOP

[edit] Rust

fn rot13 (string: ~str) -> ~str {
fn rot13u8 (c: u8) -> u8 {
match c {
97..109 => c+13,
65..77 => c+13,
110..122 => c-13,
78..90 => c-13,
_ => c
}
}
std::str::from_utf8_owned(string.as_bytes().map(|c| rot13u8(*c))).unwrap()
}
 
fn main () {
let a = rot13(~"abc");
assert_eq!(a, ~"nop");
}

[edit] 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.

[edit] 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))))
 

[edit] sed

The two translations (upper and lower case) are separate only for documentation and ease of understanding; they could be combined into one command.

y/abcdefghijklmnopqrstuvwxyz/nopqrstuvwxyzabcdefghijklm/
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/NOPQRSTUVWXYZABCDEFGHIJKLM/

[edit] 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;

[edit] Sidef

# Returns a copy of 's' with rot13 encoding.
func rot13(s) {
s.tr('A-Za-z', 'N-ZA-Mn-za-m');
}
 
# Perform rot13 on standard input.
STDIN.each { |line| print rot13(line) }

[edit] Slate

A shell script:

#!/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.

Normal functions:

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'

[edit] 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.

"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.

[edit] SNOBOL4

Works with: Macro Spitbol
Works with: Snobol4+
Works with: CSnobol
*       # 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

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.

[edit] Standard ML

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

[edit] SQL

Works with: T-SQL
 
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)
 

[edit] 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
}
Using
Library: TclX
we can write
package require Tclx
proc rot13 str {
translit "A-Za-z" "N-ZA-Mn-za-m" $str
}

[edit] TorqueScript

--Ipquarx 8:45 PM

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

[edit] 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.

:"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

[edit] TXR

Via definition and subsequent use of a named filter.

@(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"))
@(repeat)
@line
@ (output :filter rot13)
@line
@ (end)
@(end)

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.

Via TXR Lisp:

@(do
(defun rot13 (ch)
(cond
((<= #\A (chr-toupper ch) #\M) (+ ch 13))
((<= #\N (chr-toupper ch) #\Z) (- ch 13))
(t ch)))
 
(each ((l (gun (get-line nil))))
(put-line [mapcar rot13 l])))

[edit] UNIX Shell

[edit] Bourne Shell

#!/bin/sh
function rot13 () {
tr '[a-m][n-z][A-M][N-Z]' '[n-z][a-m][N-Z][A-M]'
}
 
cat ${1+"$@"} | rot13

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

[edit] 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

[edit] 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.

#import std
 
#executable (<'parameterized','default-to-stdin'>,<>)
 
rot = ~command.files; * contents:= ~contents; * * -:~& -- ^p(~&,rep13~&zyC)~~ ~=`A-~ letters

[edit] Vedit macro language

Using ROT13.TBL from here

Translate_Load("ROT13.TBL")
Translate_Block(0, File_Size)

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.

[edit] Visual Basic .NET

Platform: .NET

Works with: Visual Basic .NET version 9.0+
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

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.

[edit] Wart

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

Output:

(rot13 "Moron")
=> "Zbeba"

[edit] X86 Assembly

Using Linux/FASM.

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

[edit] XPL0

Usage: rot13 <infile.txt >outfile.txt

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

[edit] 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.

[edit] zkl

File rot13.zkl:

#!/home/craigd/Bin/zkl
 
var letters=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var rot13Letters=
"NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm";
 
fcn rot13(text){
text.apply(fcn(c){try{ rot13Letters[letters.index(c)] }
catch{ c }})
}
text:=(vm.arglist or File.stdin);
text.pump(File.stdout,rot13); // text is stdin or list of strings
./rot13.zkl Hello " " 'World!'
Uryyb Jbeyq!
echo 'Hello World!' | ./rot13.zkl
Uryyb Jbeyq!

[edit] ZX Spectrum Basic

Translation of: QBasic
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$
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox