# ROT-13 transform standard input

The challenge: To read an input of arbitrary length and produce the ROT13 of the input. All characters besides A-Z should be copied to the output verbatim, and case should be preserved if possible.

Any language that can read and write standard streams is fair game.

• The problem shouldn't be a tag, so I removed ROT13, just an FYI – Nick Berardi Jan 27 '11 at 21:18
• Don't you mean A-Za-z (to count both upper- and lower-case) ? – Joey Adams Jan 27 '11 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. – Nakilon Jan 30 '11 at 18:59
• Saying xor is not encryption is like saying a+b is not math. – Nakilon Jan 30 '11 at 19:02
• Tags are used to categorize questions and help search similar questions. The cryptography tag (from Greek kryptós, "hidden, secret"; and graphein, "writing") in particular is for encryption and decryption problems. All encryption and decryption, not only those that are secure for modern applications. – Angs Dec 3 '16 at 10:33

# Bash, 23 bytes

tr A-Za-z N-ZA-Mn-za-m

• I'm without access to bash at the moment, but I think this should work: tr A-za-m N-ZA-z (16 chars) – Nabb Feb 2 '11 at 7:24
• @Nabb: Nice to see you, GolfScript-meister! :-D I think your solution here would break the stipulation that "All characters besides A-Z should be copied to the output verbatim". – Chris Jester-Young Feb 2 '11 at 12:07
• @Chris: Yep, looks like you're right. – Nabb Feb 3 '11 at 2:22
• @Nabb: No, to me it looks as if he's wrong. Or may you show an example? – user unknown Feb 6 '11 at 5:56
• @user unknown: Type in [\\]^_ in the input. It will come back as NOPQRS rather than [\\]^_, at least in the version of tr I have. (Those are the six characters in ASCII that lie between Z and a. Obviously, all other characters will work correctly.) – Chris Jester-Young Feb 6 '11 at 7:07

## Bash - 5 chars

rot13


• Two downvotes so far (with no comments), but no downvotes for the question. I assume that means it's ok to ask trivial codegolfs but not to give the trivial answer. Harder codegolfs please! – gnibbler Jan 30 '11 at 20:49
• Which bash-version? I don't have a build-in rot13. bash --version GNU bash, Version 4.0.33(1)-release (i486-pc-linux-gnu) – user unknown Feb 6 '11 at 5:21
• I'd have submitted this as rot13 - 0 chars... ;) – boothby Mar 9 '13 at 18:10
• 'tis coreutils my friend, not Bash – TheDoctor Mar 17 '14 at 0:18
• erm... no. my bash (Ubuntu 13.10) says "command not found, you can install this program by sudo apt-get install bsdgames" – user16402 Apr 9 '14 at 17:43

## Befunge - 7x30 = 210 6x26 = 156 characters

New streaming version that supports both upper and lower case and should support unlimited input.

v,<               <<     <
^-4-9<    >:"A"\|
>:"a"\|     #>:"Z"|
>~:0| #    >:"z"|
,    @ |    <"m":<v"M":<
^  +4+9<    ^      <


### The old version

This stores the values inside its own source code. Really shows off how horrible it is to try and output stored values in the same order that you receive them. Only supports lowercase characters.

vp0p11:+1g11<      < <
v                    ^-4-9<
v    >:"a"\|>:"z"|>:"m"|
>~:0|      >^     >^#
^+4+9<
>$011g1+0p>12g1+:12p0g:v ^ ,_@  I'm not sure exactly what limitations this has, using http://www.quirkster.com/iano/js/befunge.html as the interpreter it does appear to break with large inputs. • You can remove the whitespace at the end of lines. – Zacharý Dec 31 '17 at 18:59 # Python 2, 34 bytes print raw_input().encode('rot13')  • -1 I think it is cheating that you are using a built in library. – Glenn Nelson Jan 27 '11 at 21:23 • I've used them in every code golf I took part in... Also if using python's standard lib is cheating, how is using tr not? – Juan Jan 27 '11 at 21:27 • @Anon In any case, it's an anwser you just ignore.. It's not off target, there's not any rules set by the OP nor by the community. Sure, maybe mine is not an award winning solution, like the one using tr that kicks ass. But it's not a joke, I'm leveraging the power of python to reduce the count, just like any other would do. – Juan Jan 27 '11 at 21:37 • @Glenn: on the contrary, I have never seen a code-golf thing that say so. Neither do codegolf.com, golf.shinh.org or SPOJ SHORTEN. – hallvabo Jan 27 '11 at 23:36 • @Glenn, I think library functions are fair game. It's up to the golf question to be interesting enough to not be in anyone's library or to specifically exclude. – gnibbler Jan 28 '11 at 2:09 ## Ruby - 60 57 38 37 chars Edit: And just realised Ruby strings have a tr method. puts$<.read.tr'A-Za-z','N-ZA-Mn-za-m'


### Test

input = "The challenge: To read an input of arbitrary length and produce the ROT13 of the input. All characters besides A-Z should be copied to the output verbatim, and case should be preserved if possible.

Any language that can read and write standard streams is fair game."

output = echo '#{input}' | ruby golf-rot13.rb

puts "Input:"
puts input
puts "-------"
puts "Output:"
puts output


Gives:

Input:
The challenge: To read an input of arbitrary length and produce the ROT13 of the input. All characters besides A-Z should be copied to the output verbatim, and case should be preserved if possible.

Any language that can read and write standard streams is fair game.
-------
Output:
Gur punyyratr: Gb ernq na vachg bs neovgenel yratgu naq cebqhpr gur EBG13 bs gur vachg. Nyy punenpgref orfvqrf N-M fubhyq or pbcvrq gb gur bhgchg ireongvz, naq pnfr fubhyq or cerfreirq vs cbffvoyr.

Nal ynathntr gung pna ernq naq jevgr fgnaqneq fgernzf vf snve tnzr.

• You don't need the space after puts, and 'A-z' is a shortcut for 'A-Za-z' – Ventero Feb 2 '11 at 14:52
• @Ventro: Thanks, after a bit of testing it seems 'A-z' is actually 'A-Z[\]^_a-z', damn ascii having characters between Z and a. – Nemo157 Feb 2 '11 at 20:50
• Essentially the same but 35 characters: puts gets.tr'A-Za-z','N-ZA-Mn-za-m'. – Michael Kohl Mar 13 '11 at 23:43
• @Michael: Except gets only returns the first line, using $<.read reads until EOF. The question doesn't say anything about whether the input can contain new lines so I just erred on the side of caution. – Nemo157 Mar 14 '11 at 0:22 • Fair enough, but since the exercise specification only mentioned "arbitrary length" but said nothing about newlines, I'd rather err on the side of brevity in codegolf ;-) – Michael Kohl Mar 14 '11 at 7:32 # vim, 5 keystrokes Assuming normal mode and that the text is already written in the buffer: ggg?G Or, fallowing vimgolf's conventions: g?GZZ You can also invoke it as a terminal command, something like this: $ vim -c 'norm g?G' -
... multiple lines if you want ...
... terminate input with ctrl+D on a blank line >


I guess the latter would count as a "program" of 8 characters (norm g?G)

• norm g?G is short for normal g?G that makes 8 chars. – Patrick Oscity Sep 4 '14 at 15:23
• I think you can safely assume to start out on line 1, so the first gg can be left off. I would say 3 keystrokes when the file is open. – Patrick Oscity Sep 4 '14 at 15:24
• If we use vimgolf's conventions (you start in a vanilla vim having just opened the file, but need to save and quit) we also get 5 (g?GZZ). – FireFly Oct 30 '14 at 21:53

## C - 83 79 characters

main(c,b){while((c=getchar())>=0)b=c&96,putchar(isalpha(c)?b+1+(c-b+12)%26:c);}


#include <ctype.h>
#include <stdio.h>

int main(void)
{
int c, base;

while ((c = getchar()) >= 0) {
if (isalpha(c)) {
base = (c & 96) + 1; /* First letter of the upper or lower case. */
c = base + (c - base + 13) % 26;
}
putchar(c);
}

return 0;
}

• Are you including the headers you include in your count? – JPvdMerwe Jan 27 '11 at 22:18
• @JPvdMerwe: I didn't include any headers in the golfed version, nor did I need to. – Joey Adams Jan 27 '11 at 22:34
• You can use the coma operator before putchar to remove a pair of braces. – Alexandru Jan 27 '11 at 23:05
• Could you explain main(c,b)? It's the first time i see this. – Alexandru Jan 27 '11 at 23:11
• @Alexandru most C compilers support main with any parameters. Also, the original C standard defines that an argument with no type is an int. Thus you get to declare ints without actually writing int. – Juan Jan 27 '11 at 23:31

## Python (117 bytes)

Here's a Python version that avoids the rot13()-method.

import sys
print"".join([chr(x/32*32+1+(x%32+12)%26if 64<x<91or 96<x<123 else x)for x in map(ord,sys.stdin.read())])

• raw_input returns one line not all input. – Alexandru Jan 27 '11 at 23:34
• you need to import sys and use sys.stdin.read(). – Alexandru Jan 27 '11 at 23:41
• @Alexandru: will do – JPvdMerwe Jan 27 '11 at 23:46
• -2 bytes if you eliminate the [] to make the list comp a generator: tio.run/… – connectyourcharger Jul 17 at 16:55

tr/// solution in Perl (39 characters), boilerplate can be removed with -p:

while(<>){y/a-zA-Z/n-za-mN-ZA-M/;print}


Using -p (23 characters including the extra switch):

perl -pe'y/a-zA-Z/n-za-mN-ZA-M/'

• Add 1 char for the p, but please remove the boilerplate! – J B Feb 6 '11 at 21:04

# R, 37 bytes

example("chartr");cat(rot(scan(,"")))


example("chartr") runs the examples for chartr, which includes the rot function, which is ROT13 by default....

DC (111 108 for the dc itself)

Ok, here it is in (mostly) dc and some sed and od magic to get it into the right format for the code. If you don't count the input thing (echo -n MESSAGE |) it's 160 bytes:

od -An -t dC|sed 's/^\ *//;s/\ \{2,3\}/\n/g'|dc -e'[13+26%]sm[65-lmx65+]su[97-lmx97+]sl[96<b64<dPc]sa[91>c]sd[123>e]sb[lux]sc[llxdd]se[ddddlaxlrx]sy[?z0<y]dsrx'


As a point of interest, the dc programme itself is only a 108 bytes long, shorter than the non-library python version. It even preserves case and punctuation, and beats Javascript in the above submission! If only I could better parse the output of od, or better yet replace it altogether.

EDIT: It's worth noting that the question doesn't indicate a trailing new line 10P which saves me three further bytes.

EDIT 2: There's no specification for the format of the input, so I assume it's taken in as is convenient for my programme :P

# Befunge-93, 85 (grid: 41x3=123)

This is an ancient question, but I thought I'd revive it to post a slightly nicer Befunge answer.

#v_~::" "/2%" "*-::"@"!#v_"Z"#v#!_1
v> "M"2*1\-34*1+*+    1:>$! _:"."-!#@_ >,^  You can test it here. Enter a single character at a time; it terminates upon entering a . character (you can change that by modifying the "." near the right side of the second row). Works with upper and lower case, as well as punctuation, and with no limit to input. I don't expect this to get a ton of upvotes or anything, but I just wanted to demonstrate how awesome Befunge actually is that you can do a little better than the other answer. I could probably make it even shorter in Befunge-98. • You can add my snippet from here to have an inline interpreter, if you want. :) – Ingo Bürk Oct 30 '14 at 21:48 • Ooh, I haven't really investigated snippets yet. I'll take a look, thanks! – Kasran Oct 30 '14 at 22:17 • This doesn't work if there is a space in the input. It goes into an infinite loop in the sequence >$! _ because you've got two zeros on the stack at that point when you are expecting a non-zero value. – James Holderness Jan 3 '18 at 17:30

# PHP - 10398 80 characters

(not using str_rot13())

<?=preg_replace('#[a-zA-Z]#e','chr(($x=ord("\0"))-$x%32+1+($x%32+12)%26)',cat);  ## Delphi, 110 var c:Char;begin repeat Read(c);Write(Chr(Ord(c)+(Ord(c in['A'..'M'])-Ord(c in['N'..'Z']))*13));until EOF;end.  • var c:Char;begin repeat Read(c);Write(Chr(Ord(c)+(Ord(c in['A'..'M'])-Ord(c in['N'..'Z']))*13));until EOF;end. saves one character :) – Wouter van Nifterick Mar 13 '11 at 21:36 • @Wouter van Nifterick : Good spot! I'll update it accordingly – PatrickvL Mar 13 '11 at 23:28 ## Haskell, 100 characters a%b=([a..b]++) main=interact$map$toEnum.((0%64$78%90$65%77$91%96$110%122$97%109$[123..])!!).fromEnum  Perl6 (54) $*IN.lines».trans("a..zA..Z"=>"n..za..mN..ZA..M").say


Java 251 chars

public class r{public static void main(String[] a){String s = a[0];for(int i=0;i<s.length();){char c=s.charAt(i++);if(c>='a'&&c<='m')c+=13;else if(c>='n'&&c<='z')c-= 13;else if(c>='A'&&c<='M')c+=13;else if(c>='A'&&c <='Z')c-=13;System.out.print(c);}}}


# Python 3 (107)

Ok, I promise to stop answering this question now, but I felt compelled to beat the DC answer in Python. This probably reflects poorly on me as a person :).

import sys;[print(x.isalpha()and chr((ord(x)&96)+1+(ord(x)%32+12)%26)or x,end='')for x in sys.stdin.read()]


# C: 69 68 characters

Alright, I know this thread is long dead, but I couldn't stand the (long) C-solution which doesn't even compile on Clang (but does on GCC).

main(c){putchar(isalpha(c=getchar())*((c|32)<110?13:-13)+c);main();}


It is probably almost still squeezable. It certainly was squeezable. And not only was it squeezable, it was possible to make it recursive.

# 05AB1E, 13 12 bytes

Saved a byte thanks to robbie0630

ADu)øJD2äRJ‡


Try it online!

Explanation

ADu           # push lower-case and uppercase alphabet
)øJ        # zip, flatten and join, producing aAbB..zZ
D2äRJ   # split a copy in 2 pieces, reverse and join producing nNoO..mM
‡  # translate input by replacing members of the alphabet
# with the corresponding member of the rot-13 alphabet
# implicitly display

• I ran through this with --debug, and it seems like the ˜ is a no-op in this case and can be cut out. – robbie Feb 15 '18 at 3:31
• @robbie0630: True. No idea why I had that in. Thank you :) – Emigna Feb 15 '18 at 6:50

## PHP - 41 Characters

while($r=fgets(STDIN))echo str_rot13($r);

• -1 for rep-whoring. – Raynos Feb 3 '11 at 21:39

JavaScript 1.8, 106

alert(prompt().replace(/\w/g,function(c)String.fromCharCode(c.charCodeAt()+(c.toLowerCase()<'n'?13:-13))))

JavaScript, 115

alert(prompt().replace(/\w/g,function(c){return String.fromCharCode(c.charCodeAt()+(c.toLowerCase()<'n'?13:-13))}))

This solution solves the problem by adding 13 to the character code if the character in question is in the first half of the alphabet, or subtracting 13 if it's in the second half.

• You can save 7 characters by replacing +(c.toLowerCase()<'n'?13:-13)) with -13+26*/[a-m]/i.test(c). – Jacob Jun 11 '14 at 6:15

# CHIQRSX9+, 1

R


You just have to use the right tool for the problem.
CHIQRSX9+ is Turing complete, and it can read and write from standard channels with C.

• @nyuszika7h The language was invented before this question was written, so it is valid. – Johannes Kuhn Jan 2 '14 at 20:25
• It's still one of the things it was invented for, though. Seems like cheating to me. – nyuszika7h Jan 2 '14 at 21:11
• @nyuszika7h And golfscript was invented to win in code-golf challenges. Do you think that is cheating too? – Johannes Kuhn Jan 2 '14 at 21:12
• @Mego It's hardly fair to apply those standards here when they were written a year after this answer. – Doorknob Nov 14 '15 at 19:32
• MetaGolfScript is forbidden by a different rule – Mego Nov 15 '15 at 14:48

## C, 136 bytes

I have never felt like any of my solutions are good enough to post on here, but made this for fun, and figured that it will be my gateway drug into code golf.

#define z(x) c>=x&&c<x+13
#define q(w) c>=w&&c<w+13
main(c){for(;(c=getchar())>=0;putchar(z('A')||z('a')?c+13:q('M')||q('m')?c-13:c));}

• Welcome to Programming Puzzles and Code Golf Stack Exchange. Great first answer. And just for the record, we all feel that way sometimes, just know that anything that you create is "good enough" somewhere. – GamrCorps Feb 22 '16 at 18:21
• Everything here on PPCG is just for fun (or imaginary internet points) -- please, don't feel the work you've done to craft a solution isn't "good enough" – cat Feb 23 '16 at 23:36
• Thanks for all the support. I think posting something was all I needed to get my head in gear. I am going to try my hand at more of these challenges soon. – Tormyst Feb 24 '16 at 2:10

# Javascript, 177 bytes

This assumes that there are two functions, print and readLine:

f=String.fromCharCode;print(readLine().replace(/[a-z]/g,function(a){return f((a.charCodeAt(0)-84)%25+97);}).replace(/[A-Z]/g,function(a){return f((a.charCodeAt(0)-52)%25+65);}))


# 8086 Machine Code, 27 bytes

Unassembled:

        STLOOP:
8B D0       MOV  DX, AX         ; save original char in DL
0C 20       OR   AL, 020H       ; lowercase the char
3C 61       CMP  AL, 'a'        ; is char less than 'a'?
7C 0F       JL   STCHR          ; if so, do not rotate
3C 7A       CMP  AL, 'z'        ; is char greater than 'z'?
7F 0B       JG   STCHR          ; if so, do not rotate
B6 0D       MOV  DH, 'n'-'a'    ; add or subtract 13
3C 6E       CMP  AL, 'n'        ; is char less than 'n'?
F6 DE       NEG  DH             ; otherwise add -13
92          XCHG AX, DX         ; original char back to AL
02 C4       ADD  AL, AH         ; add 13 or -13 to original char
STCHR:
AA          STOSB               ; store converted byte into DI, advance DI
E2 E5       LOOP STLOOP         ; continue loop through string


Input string in SI, length in CX. Output string buffer at DI.

Test IBM PC DOS program output:

r l=drop 13 l++take 13 l
t=['a'..'z']
s=['A'..'Z']
main=interact$map(\x->maybe x id$lookup x$zip(t++s)$r t++r s)


## K, 31

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

• {x^a(,/-13 13#\:a:.Q.A)?x} for 26 bytes – streetster Jan 31 '18 at 21:31

## Tcl, 74 chars

package require [set c tcl::transform::rot];\$c 13 stdin;fcopy stdin stdout


# Javascript (165)

a=prompt();y="ABCDEFGHIJKLMNOPQRSTUVWXYZ";b=y[s="substr"](13)+y[s](0,13);y+=y[l="toLowerCase"]();b+=b[l]();o='';for(i=0;a[i];i++)o+=b[y.indexOf(a[i])]||a[i];alert(o)


or (167) as previous Javascript solution, assuming readLine and print:

a=readLine();y="ABCDEFGHIJKLMNOPQRSTUVWXYZ";b=y[s="substr"](13)+y[s](0,13);y+=y[l="toLowerCase"]();b+=b[l]();o='';for(i=0;a[i];i++)o+=b[y.indexOf(a[i])]||a[i];print(o)
`
• Since nobody said it in >2 years, welcome to PPCG! – Erik the Outgolfer Oct 6 '16 at 11:43