# ROT-13 transform standard input

Read a string of characters and produce the ROT13 of it. All characters besides [a-zA-Z] should be output verbatim. Each letter in the output may be in any case you wish (you do not have to preserve it).

ROT13 is a simple substitution cipher where each letter of the alphabet is rotated by 13 places (it doesn't matter whether you do it forward or backward, since ROT13 is it's own inverse).

# Examples

Input
Output

Hello, world!
Uryyb, jbeyq!

Code Golf and Coding Challenges is awesome.
Pbqr Tbys naq Pbqvat Punyyratrf vf njrfbzr.

Mod abuse!1!!1
Zbq nohfr!1!!1

• The problem shouldn't be a tag, so I removed ROT13, just an FYI Commented Jan 27, 2011 at 21:18
• Don't you mean A-Za-z (to count both upper- and lower-case) ? Commented Jan 27, 2011 at 21:33
• @Chris Jester-Young, it belongs to this category at wikipedia. It's part of cryptography, just not the hardest one. Anyway, I'm not longer following this site. Community dissapointed me. Sorry. GL HF. Commented Jan 30, 2011 at 18:59
• Saying xor is not encryption is like saying a+b is not math. Commented Jan 30, 2011 at 19:02
• @Nakilon: Actually, I call that arithmetic, not mathematics. *shrug* Commented Jan 30, 2011 at 19:04

# Julia 1.0, 69 bytes

(x->(c=Char(x);print(c+isletter(c)*13*(-1)^(x&31>13)))).(read(stdin))


Try it online!

### Explanation

Most of the code is an anonymous function that takes an integer codepoint and prints the corresponding ROT-13'd character:

x->(c=Char(x);print(c+isletter(c)*13*(-1)^(x&31>13)))

x->(                                                )  # Anonymous function of x
c=Char(x);                                         # Cast x to Char and save as c
isletter(c)*                     # If c is not a letter, the rest of this is
# multiplied by 0
13*(-1)^(       )    # 13, times +/- 1 according to:
x&31>13     # Low 5 bits of x are greater than 13
# I.e. x > 'M' (if x is uppercase) or x > 'm'
# (if x is lowercase)
print(                               )   # Output the resulting character


We then apply this function, vectorized, to the array of (integer) codepoints returned by read(stdin).

• 65 bytes Commented Jan 2, 2019 at 13:19

# JavaScript (Node.js), 65 bytes

o=>(b=Buffer)(b(o).map(c=>c%32<26&c>64?(c%32+13)%26+c-c%32:c))+''


Try it online!

o=>(                    // Define a function taking o and r
b = Buffer            // Assign b to Buffer
)(                      // And call on...
b(o).map(c=>          // a Buffer of the charcodes of o, mapped to...
c%32<26&c>64        // If the character is alphabetical - charcode%32 is less than 26, charcode is >64
?                 // Then
(c%32+13)%26+c-c%32 // Rot-13 the character - Mod 32, add 13, mod 26, add correct number depending on whether it's uppercase of lowercase.
:c)                 // Else return the original string
) + ''                 // Coerce to string


# Atto-8 Machine Code, 23 bytes

Decoded as hex:

E8 00 E0 C0 20 A0 61 84 00 0D 85 0D 90 0D 85 F2 90 D0 80 00 E1 01 E3


Commented disassembly listing:

# Generated by Dasm

main!
nop @dyn        # padding for alignment
x00 lda         # read from standard input
ld0 x20 orr     # clone and convert to lowercase
x61 sub         # map lowercase alphabet to 0-25
x00             # default offset is 0
x0D su2 x0D iff # if between a-m, offset is 13
x0D su2 xF2 iff # if between n-z, offset is -13
x00 sta         # write to standard output
x01 sti         # loop back to start


## K, 31

{x^(,/{x!(13_x),13#x}'.QAa)x}

• {x^a(,/-13 13#\:a:.Q.A)?x} for 26 bytes
– mkst
Commented Jan 31, 2018 at 21:31
• Assuming only rot13'ing upper case letters is acceptable, {x^a(,/|0 13_a:.Q.A)?x} for 23 bytes. Handling both upper and lower case can be done in 29 by swapping the inner lambda in @tmartin's answer for {x!,/|0 13_x}. Commented Dec 8, 2020 at 15:41

package require [set c tcl::transform::rot];$c 13 stdin;fcopy stdin stdout  # Haskell (103) Reused maybe c id$ lookup c from jloy's answer.

main=interact$map(\c->maybe c id$lookup c$[['a'..'z'],['A'..'Z']]>>=zip<*>uncurry(flip(++)).splitAt 13)  # pyg-i - 76 Bytes P(STDI.read().t({a:a-13 if(77<a<91)or a>109 else a+13 for a in M(ord,STl)}))  Python Equivient: import sys,string print(sys.stdin.read().translate({a:a-13 if(77<a<91)or a>109 else a+13 for a in map(ord,string.ascii_letters)}))  • Invalid because the interpreter is not available. – cat Commented Feb 22, 2016 at 21:29 • @cat Somehow I got the url wrong. It is fixed now. Commented Feb 23, 2016 at 23:24 ## Python: 60 bytes lambda s:''.join([chr((ord(c.lower())-84)%26+97)for c in s])  The only thing I don't like is having that .lower() in there. Any suggestions? edit: I can get rid of the .lower(), and handle capitals better, but it's 94 bytes now: lambda s:''.join([chr((ord(c)-(52if ord(c)<97else 84))%26+(65if ord(c)<97else 97))for c in s])  # C#, 94 bytes s=>{var r="";foreach(var c in s)r+=(char)(Char.IsLetter(c)?(c|32)<110?c+13:c-13:c);return r;};  Anonymous function which returns the string of characters rotated by 13 places, based on this C answer from Fors. Works for any lower or upper letters while keeping other input the same. Full program with ungolfed method and test cases: using System; namespace ROT13 { class Program { static void Main(string[] args) { Func<string, string> f = s => { var r = ""; foreach (var c in s) r += (char)(Char.IsLetter(c) ? (c | 32) < 110 ? c + 13 : c - 13 : c); return r; }; Console.WriteLine(f("TOO MANY SECRETS!")); // GBB ZNAL FRPERGF! Console.WriteLine(f("too many secrets!")); // gbb znal frpergf! Console.WriteLine(f("gbb znal frpergf!")); // too many secrets! Console.WriteLine(f("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,./")); // NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm1234567890,./ } } }  # Befunge-93, 72 67 bytes Edit: -5 bytes thanks to James Holderness <,<v!:+*"a"*""\\"{":\*"G"*"@"\\"[":::_@#+1:~ +0|_\"N"%6-55*1+%  Try it online! Kinda disappointed in the previous Befunge answers, so I wrote one with much less whitespace. # Retina, 13 bytes 13+TzlZLl_L  Try it online! The straightforward transliteration that directly applies ROT13 would be 2 bytes longer Try it online! ### Explanation The transliteration stage here is wrapped in a loop stage making it run 13 times (or until the string is not transformed anymore, which can only happen if the input string has no alphabetic characters). In the transliteration, characters in zlZL are transformed into the characters at the same positions in l_L. Here, z and Z are exactly what they look like, while l and L get converted into the lowercase and uppercase alphabets. The final letters of those alphabets are ignored because they already appear earlier in the string, and _ is just a placeholder to make the uppercase alphabet line up correctly. The result is transforming each letter into the next one (a->b,b->c,...,z->a); doing this 13 times is ROT13. # Powershell, 77 bytes -join($args|% t*y|%{[char]((("$_"-match'[a-m]')-("$_"-match'[n-z]'))*13+$_)})  Test script: $f = {

-join($args|% t*y|%{[char]((("$_"-match'[a-m]')-("$_"-match'[n-z]'))*13+$_)})

}

@(

,("Hello!","Uryyb!")
,("HELLO","URYYB")
,("URYYB","HELLO")
,("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz","NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm")
,("Why did the chicken cross the road?
Gb trg gb gur bgure fvqr!",
"Jul qvq gur puvpxra pebff gur ebnq?
To get to the other side!")

) | % {
$s,$expected = $_$result = &$f$s
"$($result-eq$expected):$result"
}


Output:

True: Uryyb!
True: URYYB
True: HELLO
True: NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm
True: Jul qvq gur puvpxra pebff gur ebnq?
To get to the other side!


# Python 3, 70 bytes

a=input()
for i in a:print(end=i.isalpha()*chr(65+(ord(i)-52)%26)or i)

• Your proposed solution does not work with lowercase letters. It's not explicitely specified in the challenge though, so I'm not sure if your answer is valid. Commented Feb 27, 2019 at 18:17

# PHP - 27 Bytes

<?=str_rot13(fgets(STDIN));


# naz, 176 bytes

2a2x1v6a8m2x2v9a4a2x3v9a5a2x4v5a2x5v9a4a2x6v9a5a2x7v1x1f1r3x1v7e3x5v5g3x2v2g8f0x1x2f3x4v3l8f0x1x3f3x3v4g9a4a8f0x1x4f9s4s8f0x1x5f3x7v6l8f0x1x6f3x6v4g9a4a8f0x1x7f0a0x1x8f1o1f0x1f


The most involved naz solution I've written so far. This program subtracts 13 from every letter in standard input that's greater than M, and adds 13 to every other letter - whether lowercase or uppercase.

It does use a lot of logic to determine what's a letter or not, so I wouldn't be surprised if this could be improved upon.

Works for any input string terminated with the control character STX (U+0002).

Explanation (with 0x commands removed)

2a2x1v                     # Set variable 1 equal to 2
6a8m2x2v                   # Set variable 2 equal to 64 ("@")
9a4a2x3v                   # Set variable 3 equal to 77 ("M")
9a5a2x4v                   # Set variable 4 equal to 91 ("[")
5a2x5v                     # Set variable 5 equal to 96 ("")
9a4a2x6v                   # Set variable 6 equal to 109 ("m")
9a5a2x7v                   # Set variable 7 equal to 123 ("{")
1x1f                       # Function 1
1r                     # Read a byte of input
3x5v5g         # Jump to function 5 if it's greater than variable 5
3x2v2g   # Jump to function 2 if it's greater than variable 2
1x2f                       # Function 2
3x4v3l                 # Jump to function 3 if the register is less than variable 4
1x3f                       # Function 3
3x3v4g                 # Jump to function 4 if the register is greater than variable 3
9a4a             # Otherwise, add 13 to the register,
1x4f                       # Function 4
9s4s8f                 # Subtract 13 from the register, then jump to function 8
1x5f                       # Function 5
3x7v6l                 # Jump to function 6 if the register is less than variable 7
1x6f                       # Function 6
3x6v4g                 # Jump to function 4 if the register is greater than variable 6
9a4a             # Otherwise, add 13 to the register,
1x7f                       # Function 7
0a                     # Add 0 to the register
1x8f                       # Function 8
1f                         # Call function 1


# Jelly, 12 bytes

ØAṙ13,µ;Œlyɠ


Try it online!

This takes input from STDIN

## How it works

ØAṙ13,µ;Œlyɠ - Main link. Takes no arguments
ØA           - "ABC...XYZ"
ṙ13        - Rotate 13 steps to the left
,       - Pair with the unaltered alphabet
µ      - Begin a new link with ['NOP...KLM', 'ABC...XYZ'] as argument
Œl   - Lowercase; ['nop...klm', 'abc..xyz']
;     - Concatenate; ['NOP...KLM', 'ABC...XYZ', 'nop...klm', 'abc..xyz']
ɠ - Read a line from STDIN
y  - Transliterate


# Vyxal, 10 bytes

kB½(nn13ǓĿ


Try it Online!

-4 thx to lyxal

• Try it Online! for 11 bytes. Commented May 31, 2021 at 12:47
• @lyxal Thanks, next learn to count! Commented May 31, 2021 at 20:11

# GNU AWK, 147 8+82 = 90 bytes

-lordchr argument

BEGIN{RS=".|";ORS=e}$0=RT~/[A-Za-z]/?chr(ord(RT)+(ord(tolower(RT))>109?-13:13)):RT  Try it online! After some thought, I realized it is possible to explore GNU AWK's ordchr extension to return the ASCII value of a character, saving tons of bytes. The ROT13 algorithm identifies if the letter is in the first or second half of the alphabet, adding of subtracting 13 to its ASCII value, accordingly. This code transforms every character as Record Separator, then substitutes every $0 (formerly null) for the matching record separator (RT): ROT13 modified, if it's a letter; or itself, if not.

# Ly, 65 bytes

ir[:'@Gf(123)Lf'ZGf'aLfp*!**[p'ZGsp(13)+'Z(32)l*+G[p(26)-0]p0]po]


Try it online!

I'm enjoying learning Ly, so even though this is an old challenge I decided to give it a shot...

This is pretty brute force and the result isn't short compared to other entries. But it does show how to do things like if-then conditional blocks in Ly, so maybe someone will find it useful?

This bit reads in a line of input as codepoints, reverses the stack, then loops through each character/codepoint. At the end of the loop the character is printed, rot13'd or not.

ir[                                                            o]


The first thing to do is duplicate the character with : since we need to do two operations and it's easier to make a copy of the character on the stack now and then do the first one. That first test checks to see if the current character is in "a-z" or "A-Z". It does that by stacking the results from 4 comparisons, >=A >Z >=a and >z. Then it combines those 0|1 results mathematically to figure out if we're in the right range.

   :'@Gf(123)Lf'ZGf'aLfp*!**


Then the pattern I've found works for if-then is used to conditionally apply the rot-13 logic only when we get an alphabetic character. That pattern is ...test...[p...then-code...0]p. So in this case that's these bits.

                            [p                              0]p


And the code to apply the rotation starts by figuring out and remembering if the character is uppercase or not. After the s command, the backup cell will be 1|0 to indicated whether or not the character is uppercase.

                              'ZGsp


After that, the code adds 13 to the codepoint, then constructs what the max codepoint value is. It's either Z or z depending on the case of the original character. The l command pushed the backup cell (upper/lower flag) onto the stack so we use that to switch the Z to z if necessary.

                                   (13)+'Z(32)l*+


Once that max codepoint is on the stack the code conditionally subtracts 26 if the rotated number it too high.

                                                 G[p(26)-0]p


At that point, the character we want to print is on top of the stack.

# SM83/Z80, 29 bytes

Input string at (de), output to (hl).

• SM83 version
1A 13 47 CB AF D6 41 38
0E FE 1A 30 0A FE 0D 78
38 02 D6 1A C6 0D 47 78
22 B7 20 E4 C9

• Z80 version (changes in »German guillemets« except for second bytes of jr for same effective offset¹)
1A 13 47 CB AF D6 41 38
10 FE 1A 30 0C FE 0D 78
38 04 D6 1A C6 0D 47»70
23 04 10«E6 C9


Disassembly and explanation:

rot13:
ld a,(de)       ; 1A        load character
inc de          ; 13        increment
ld b,a          ; 47        save copy
res 5,a         ; CB AF     clear fifth bit
sub 65          ; D6 41     subtract 'A'
jr c,put        ; 38 0E/10  if borrowed, wasn't letter
cp 26           ; FE 1A     is it 26 or more now?
jr nc,put       ; 30 0A/0C  if didn't borrow, wasn't letter
cp 13           ; FE 0D     compare against 13
ld a,b          ; 78        load original
jr c,notsub     ; 38 02/04  if carry, was greater than 13
sub 26          ; D6 1A     subtract 26 if was greater
notsub:
ld b,a          ; 47        store into b
put:                ;           b now contains rot13 version
#ifdef SM83
ld a,b          ; 78        move into a
ld (hl+),a      ; 22        store and increment
or a            ; B7        test if zero
jr nz,rot13     ; 20 E4     if not, loop
#else
ld (hl),b       ; 70        store
inc hl          ; 23        and increment
inc b           ; 04        if b was 0, it's now 1
djnz rot13      ; 10 E6     jump back if b is 1 (and decrement)
#endif
ret             ; C9        return


It's a bit interesting that both CPUs have a way of saving a byte that the other doesn't. The SM83 has autoincrement addressing, while the Z80 has a way to jump if b is 1.

¹ Apparently Z80 relative jump instructions are measured from the start, while SM83's are from the end. (So 18 00 is an infinite loop for Z80 and a three-cycle two-byte no-op for SM83.)

# Alice, 129 bytes

vv2++3a-A'<
a    > Ko= h-A'.<
#  >@o Ko<>.'Zh-=oK
>wI.=>.'a-h=oK Ko<
*  >^#va2++3a-a'<
6    +*   >.'zh-=oK
>+%'A^>6+%'a+oKo<


Try it online!

## Ungolfed

v                      >oK
>.'A-h=oK
>@     >.'Zh-=oK   >'A-a3++2a*6+%'A+oK
>oK
>wI.=>.'a-h=oK
>'a-a3++2a*6+%'a+oK
>^     >.'zh-=oK
>oK


# Python 3, 60 bytes

import this
print("".join(this.d.get(c,c)for c in input()))


# K (ngn/k), 40 bytes

c\$@[!256;c@!26;:;(c:"aA"+\:)26!-13+!26]


Try it online!

# JavaScript ES6 (155 bytes)

Here is a Caesar cipher that preserves case in in ES6.

// 155 bytes
r=s=>((f,n,m,u,l)=>[...s].map(c=>(x=>x>=u&&x<=u+n?f((x-u+m)%n+u):x>=l&&x<=l+n?f((x-l+m)%n+l):c)(c.charCodeAt())).join(''))(String.fromCharCode,26,13,65,97)

// Begin unit tests
mocha.setup('bdd')
const { expect } = chai
const testCases = [{
input: "Hello, world!",
output: "Uryyb, jbeyq!",
}, {
input: "Code Golf and Coding Challenges is awesome.",
output: "Pbqr Tbys naq Pbqvat Punyyratrf vf njrfbzr.",
}, {
input: "Mod abuse!1!!1",
output: "Zbq nohfr!1!!1",
}]
describe('Caesar cipher (ROT13)', () => {
it('are all equal', () => {
for (let { input, output } of testCases) {
expect(r(input)).to.equal(output)
}
})
})
mocha.run()
<link href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.3.4/mocha.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.4.1/chai.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.3.4/mocha.js"></script>
<div id="mocha"></div>

Here is one that is 187 bytes (+32 bytes), but no code duplication:

r=s=>((b,f,n,m,u,l)=>[...s].map(c=>(x=>b(u,x,n)?f(u,x,n,m):b(l,x,n)?f(l,x,n,m):c)(c.charCodeAt())).join(''))((v,x,n)=>x>=v&&x<=v+n,(v,x,n,m)=>String.fromCharCode((x-v+m)%n+v),26,13,65,97)


At 192 bytes (+37 bytes), this one is a bit larger, but it builds a lookup and does regex replace:

r=s=>(l=>s.replace(/\w/g,c=>l[c]))(((f,z)=>f(z.map(c=>c.toLowerCase()),f(z,{})))((s,o)=>s.reduce((m,c,i)=>({...m,[c]:s[(i+13)%26]}),o),Array.from({length:26},(_,i)=>String.fromCharCode(i+65))))


## Scala 108

def m(a:Int,z:Int,c:Int)=if(c>=a&&c<z)a+((c-a+13)%26)else c
"Ok?".map(c=>print(m(65,91,m(97,123,c)).toChar))


ungolfed:

def m (a: Int, z:Int, c:Int) = if (c >= a && c <= z) a+((c-a+13)%26) else c
"Ok?".foreach (c => print (m ('A', 'Z', m ('a', 'z', c)).toChar))


result:

Bx?


Mathematica 102

StringReplace[Input[],
Join@@Table[Rule@@FromCharacterCode/@{i+c,Mod[i+13,26]+c},{c,{65,97}},{i,0,25}]]


# JavaScript 135

s=prompt(),o='',i=0
while((c=s.charCodeAt(i++)))c+=c>64&&c<91?c<52?13:-13:c>96&&c<123?c<109?13:-13:0,o+=String.fromCharCode(c)


# Scala (96 chars)

def r(s:String)=s.map{c⇒val m = if(c<91)65 else 97
if(c.isLetter)
((c+13-m)%26+m).toChar
else c}


# J, 32 29 bytes

a.{~3&u:+13*2|&.>:'@MZmz'&I.


Try it online!

# Japt, 28 bytes

c_d)è"%l")?Z|H)<#n?Z+D:Z-D:Z


Try it!

c_d)è"%l")?Z|H)<#n?Z+D:Z-D:Z
c_                                # map input string through a function
d)è"%l")?                       # regex check if current character is a letter
Z|H)<#n?               # is it less than the letter n?
Z+D:           # if yes, then add 13
Z-D:       # otherwise, subtract 13
Z      # not a letter, do not transform

• 20 bytes using replace and switching to v2.0a1. There must be a shorter way, though. Commented Feb 27, 2019 at 17:42
• 18 bytes Commented Feb 27, 2019 at 17:45
• Nice - I had not tried the beta version yet. Looks like regex may have improved?
– dana
Commented Feb 27, 2019 at 17:47
• Yeah, but it's bugged to hell at the moment - only single character class work; anything wrapped in / won't. Commented Feb 27, 2019 at 17:50
• Commented Feb 27, 2019 at 17:50