39
\$\begingroup\$

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.

\$\endgroup\$
13
  • 3
    \$\begingroup\$ The problem shouldn't be a tag, so I removed ROT13, just an FYI \$\endgroup\$ – Nick Berardi Jan 27 '11 at 21:18
  • 2
    \$\begingroup\$ Don't you mean A-Za-z (to count both upper- and lower-case) ? \$\endgroup\$ – Joey Adams Jan 27 '11 at 21:33
  • 6
    \$\begingroup\$ @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. \$\endgroup\$ – Nakilon Jan 30 '11 at 18:59
  • 19
    \$\begingroup\$ Saying xor is not encryption is like saying a+b is not math. \$\endgroup\$ – Nakilon Jan 30 '11 at 19:02
  • 3
    \$\begingroup\$ 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. \$\endgroup\$ – Angs Dec 3 '16 at 10:33

51 Answers 51

1
2
1
\$\begingroup\$

Tcl, 74 chars

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

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)
alert(o)
\$\endgroup\$
1
\$\begingroup\$

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)}))
\$\endgroup\$
2
  • \$\begingroup\$ Invalid because the interpreter is not available. \$\endgroup\$ – cat Feb 22 '16 at 21:29
  • \$\begingroup\$ @cat Somehow I got the url wrong. It is fixed now. \$\endgroup\$ – Ian D. Scott Feb 23 '16 at 23:24
1
\$\begingroup\$

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])
\$\endgroup\$
1
\$\begingroup\$

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,./
        }
    }
}
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
0
1
\$\begingroup\$

Retina, 13 bytes

13+T`zlZL`l_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.

\$\endgroup\$
1
\$\begingroup\$

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!
\$\endgroup\$
1
\$\begingroup\$

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
      3x1v7e               # Jump to function 7 if it equals variable 1
            3x5v5g         # Jump to function 5 if it's greater than variable 5
                  3x2v2g   # Jump to function 2 if it's greater than variable 2
                        8f # Otherwise, jump to function 8
1x2f                       # Function 2
    3x4v3l                 # Jump to function 3 if the register is less than variable 4
          8f               # Otherwise, jump to function 8
1x3f                       # Function 3
    3x3v4g                 # Jump to function 4 if the register is greater than variable 3
          9a4a             # Otherwise, add 13 to the register,
              8f           # then jump to function 8
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
          8f               # Otherwise, jump to function 8
1x6f                       # Function 6
    3x6v4g                 # Jump to function 4 if the register is greater than variable 6
          9a4a             # Otherwise, add 13 to the register,
              8f           # then jump to function 8
1x7f                       # Function 7
    0a                     # Add 0 to the register
1x8f                       # Function 8
    1o1f                   # Output, then jump to function 1
1f                         # Call function 1
\$\endgroup\$
0
\$\begingroup\$

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?
\$\endgroup\$
0
\$\begingroup\$

Mathematica 102

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

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)
\$\endgroup\$
0
\$\begingroup\$

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}
\$\endgroup\$
0
\$\begingroup\$

J, 32 29 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Python 3, 70 bytes

a=input()
for i in a:print(end=i.isalpha()*chr(65+(ord(i)-52)%26)or i)
\$\endgroup\$
1
  • 2
    \$\begingroup\$ 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. \$\endgroup\$ – Nathan.Eilisha Shiraini Feb 27 '19 at 18:17
0
\$\begingroup\$

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

PHP - 27 Bytes

<?=str_rot13(fgets(STDIN));
\$\endgroup\$
0
\$\begingroup\$

T-SQL, 80 bytes

The TRANSLATE function was introduced in SQL Server 2017.

Input is taken from the column I of the table T.

SELECT TRANSLATE(I,A+B,B+A)FROM(VALUES('ABCDEFGHIJKLM','NOPQRSTUVWXYZ'))V(A,B),T

SQL Fiddle

\$\endgroup\$
0
\$\begingroup\$

Zsh, 126 .. 102 bytes

Shell builtins only. Rotates any letter in A-Za-z, using decimal-ascii conversion. Try it Online!

r()printf ${(#)$((13+$1+(##$X-$1)%26))}
for X (${(s::)1})case $X {[A-Z])r 52;;[a-z])r 84;;*)printf $X}

Previously: 126bytes 112bytes 106bytes
Initial (wrong) solutions: 56bytes 83bytes

\$\endgroup\$
0
\$\begingroup\$

Google Sheets, 144

  • Input: A1 (Given named range "A", +1 score)
  • Column B: =ArrayFormula(CODE(MID(A,SEQUENCE(LEN(A)),1, given named range "B", +1 score
  • Final output: =ArrayFormula(JOIN(,IF(B=0,,CHAR(IF((B>64)*(B<91),B+13*-1^(B>77),IF((B<97)+(B>122),B,B+13*-1^(B>109
\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.