# Caesar Shifting

A Caesar shift is probably something we're all familiar with.

(You might be even doing it as a homework task. If so, please don't copy these answers, your teacher almost certainly doesn't want anything like the answers here.)

Just in case you aren't, a Caesar shift is a very simple form of cipher. It takes a string to be ciphered and an integer. Then for every alphabetical character in the string, perform the following transformation:

1. Work out the character's position in the alphabet (0 based).
3. While the number is bigger than 25, subtract 26 from it.
4. Work out the position of the alphabet it is in.

Leave the rest of the characters unshifted.

Capital letters have to be respected because what is English without capital letters?

Examples:

abcdefghijklmnopqrstuvwxyz 1 -> bcdefghijklmnopqrstuvwxyza
Spam spam spam sausage and spam! 13 -> Fcnz fcnz fcnz fnhfntr naq fcnz!
abcdefghijklmnopqrstuvwxyz 52 -> abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz -1 -> zabcdefghijklmnopqrstuvwxy
ABCxyz 3 -> DEFabc

## Assumptions

• You may receive any printable ASCII character
• The input number can be negative and will always be bigger than -128 and less then 128 (-128<x<128)
• You must be able to encode capital letters and non-capital letters reversibly.
• You must create a full program, not just a function or snippet
• You will get your input from STDIN or closest alternate
• The characters that need to be shifted are ASCII codepoints 0x41 - 0x5A and 0x61-0x7A - upper and lower case letters

• Upper case letters should stay upper
• Lower case letters should stay lower
• Characters not in this range should be left as they are
• Note for this challenge, you only have to cipher strings, you don't have to be able to solve them automatically (but giving -x will reverse the cipher)

Since this is a catalog, languages created after this challenge are allowed to compete. Note that there must be an interpreter so the submission can be tested. It is allowed (and even encouraged) to write this interpreter yourself for a previously unimplemented language. Other than that, all the standard rules of must be obeyed. Submissions in most languages will be scored in bytes in an appropriate preexisting encoding (usually UTF-8).

## Catalog

The Stack Snippet at the bottom of this post generates the catalog from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.

## Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

## Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

## Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the snippet:

## [<><](https://esolangs.org/wiki/Fish), 121 bytes

• "You might be even doing it as a homework task. If so, please don't copy these answers, your teacher almost certainly doesn't want anything like the answers here." I wonder what would happen if you handed a teacher a 90-byte kludge of messy characters and shortcuts... Dec 19 '15 at 1:43

# Pyth, 13 bytes

uXGH.<HQrBG1z

Test suite

Basically, we start with the two strings we want to caesar shift, the lowercase and uppercase alphabets. The list containing both of these is generated by rBG1, bifurcate on uppercase. Then, we reduce over this list, starting with the input string and translating first lowercase, then uppercase letters by the appropriate shift.

• Very nice, I keep forgetting bifurcation exists... :P Dec 18 '15 at 15:30

# Pyth, 16

XXzG.<GQJrG1.<JQ

Try it online or run a Test Suite

• +1 for Star Wars input, even though I hate esolangs. Dec 18 '15 at 16:06

# Bash + bsd-games package, 21

caesar $[($1+130)%26]

Builtins FTW! Almost feels like Mathematica. Pyth answers are still shorter though.

Input string read from STDIN and integer from command-line. e.g.:

$./caesar.sh 13 <<< "Spam spam spam sausage and spam!" Fcnz fcnz fcnz fnhfntr naq fcnz!$

Or if you don't like the builtin:

# Bash + coreutils, 63

printf -va %s {a..z}
t=${a:$1%26}${a:0:$1%26}
tr A-Z$a${t^^}$t • It seems to me that the coreutils version doesn't work with -127 and/or 127? – Neil Dec 19 '15 at 1:29 • @Neil Yes. Good catch. Fixed. Dec 19 '15 at 22:54 # JavaScript (ES6), 122118114 111 bytes alert((p=prompt)().replace(/[a-z]/gi,c=>String.fromCharCode((x=c.charCodeAt(),a=x&96,x-a+n+129)%26-~a),n=+p())) Saved 4 bytes thanks to @Neil! ## Explanation First prompt takes the input string. The second is the number to shift each letter by. alert( (p=prompt)() // get input string .replace(/[a-z]/gi,c=> // for each letter String.fromCharCode(( x=c.charCodeAt(), // x = code of character a=x&96, // a = index of letter a (-1) in same capitalisation x-a+n+129)%26-~a // add N to the letter code and wrap at 26 ), // (+129 is needed to make the % work with negative numbers) n=+p() // get number to shift by ) ) • Very nice! But it doesn't work on all inputs; try "abcdefg", -26. This can be fixed by changing the formula to (x-a+n+130)%26. Dec 18 '15 at 16:15 • @ETHproductions Thanks for catching that! Dec 18 '15 at 21:36 • "You must create a full program, not just a function or snippet" Dec 19 '15 at 0:58 • @LegionMammal978 Thanks, I didn't notice that. Dec 19 '15 at 1:13 • Does a=x&96,(x-a+n+129)%26+a+1 help? – Neil Dec 19 '15 at 1:26 ## CJam, 342221 20 bytes Thanks to FryAmTheEggman for saving 1 byte. l'[,_el^_26/l~fm<ser Test it here. Input is the string to be shifte on the first line and the shift on the second. ### Explanation l e# Read the first line of input. '[, e# Push a string with all ASCII characters up to and including Z. _el e# Duplicate and convert to lower case. This only affects the letters. ^ e# Symmetric set-difference: except for the letters, each character appears in both e# sets and will be omitted from the difference, but all the letters will be included. e# This gives us "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz". _26/ e# Duplicate and split into chunks of 26 characters, separating lower and upper case. l~ e# Read the second line of input and evaluate. fm< e# Shift each of the two substrings by that many characters to the left. s e# Convert to a single string, joining both substrings back together. e# On the stack are now the input, the letters in alphabetical order and the letters e# in shifted order. er e# Character transliteration: replace each occurrence of a letter with the character e# at the corresponding position in the shifted string. • @FryAmTheEggman The '[,_el^ is a tip from Dennis. I don't know what you mean about f though, it seems like fairly normal usage? Dec 18 '15 at 14:35 • I guess I just haven't read enough CJam answers :P It just seems really neat to use it as like a map but change argument order. Dec 18 '15 at 14:40 • @FryAmTheEggman actually, I don't need the @ at all. :) Dec 18 '15 at 14:42 # Java, 249 Bytes This is as short as I could get it. Reading from stdin eats a ton of bytes. A solution using command line args is noticeably shorter but, this task specified stdin for input. Input format is the String first followed by the shift number on a new line. interface C{static void main(String[]a){java.util.Scanner r=new java.util.Scanner(System.in);String s=r.nextLine();int i=(r.nextInt()+26)%26;s.chars().forEach(c->System.out.print((char)(c>64&c<91|c>96&c<123?c<91?65+(c+i-65)%26:97+(c+i-97)%26:c)));}} Using command line Arguments this solution is only 188 bytes. Input is the String as the first argument and the shift as the second. interface C{static void main(String[]a){int i=(Integer.parseInt(a[1])+26)%26;a[0].chars().forEach(c->System.out.print((char)(c>64&c<91|c>96&c<123?c<91?65+(c+i-65)%26:97+(c+i-97)%26:c)));}} ## R, 111 bytes ### code n=scan();s=scan(,"");for(l in as.numeric(sapply(s,charToRaw))){v=97;if(l<97)v=65;cat(intToUtf8((l+n-v)%%26+v))} ### ungolfed n <- scan() # input integer s <- scan(,"") # input string letter by letter z <- as.numeric(sapply(s,charToRaw)) # get ASCII index of character for (l in z){ # loop through chars v=97 # base index of not capitalized chars if(l<97)v=65 # base index of capitalized chars cat(intToUtf8((l+n-v)%%26+v)) # paste the char of the shifted index } This program takes the user input from STDIN, first the integer shifter and then the string, character by character. ## Perl, 81 bytes (+1 for the -p flag) s/[^ ]+ //;$n=$&%26;eval"y/a-zA-Z/".($x=chr(97+$n)."-za-".chr$n+96).uc$x."/"if$n

Still working on golfing it down...

Test:

pwd
$python csr.py "Spam spam spam sausage and spam\!" 13 Fcnz fcnz fcnz fnhfntr naq fcnz! Note: In the second example an escape character and "" are needed ## Python 2, 118 116 bytes s,n=input() print''.join([[c,chr((ord(c)-97+n)%26+97)][''<c<'{'],chr((ord(c)-65+n)%26+65)]['@'<c<'[']for c in s) • You might want to use lists instead of the if/else instances (codegolf.stackexchange.com/a/62/36885 ). For example, print''.join([[c,chr((ord(c)-97+n)%26+97)]['~'<c<'{'],chr((ord(c)-65+n)%26+65)]['@'<c<'[']for c in s) is a little shorter, and should work the same. (Except change the tilde to a backtick like you had before--I couldn't get the backtick to display right.) Dec 18 '15 at 17:20 ## Mathematica, 117 bytes Echo[InputString[]~StringReplace~Thread[Join[a=Alphabet[],b=ToUpperCase@a]->(c=RotateLeft)[a,d=Input[]]~Join~c[b,d]]] Takes the string, followed by a newline, followed by the shifting factor. Might still be golfable... # Perl 6, 73+1 = 74 bytes$ perl6 -pe 's:g:i/<[a..z]>/{chr ((my$o=ord ~$/)-(my$a=$o+&96+1)+BEGIN get%26)%26+$a}/' # 73+1 The first line of input is the number of characters to shift the letters up by. Usage:$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'1
abcdefghijklmnopqrstuvwxyz'
bcdefghijklmnopqrstuvwxyza
$perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \ '13 Spam spam spam sausage and spam!' Fcnz fcnz fcnz fnhfntr naq fcnz!$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'52
abcdefghijklmnopqrstuvwxyz'
abcdefghijklmnopqrstuvwxyz
$perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \ '-1 abcdefghijklmnopqrstuvwxyz' zabcdefghijklmnopqrstuvwxy$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'3
ABCxyz'
DEFabc
$perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \ '1000000000000000000000000000000000000000 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ' mnopqrstuvwxyzabcdefghijkl MNOPQRSTUVWXYZABCDEFGHIJKL # C++, 163154 152 bytes #include<cstdio> #include<cstdlib> int main(int x,char**a){for(int c,b,s=atoi(a[1]);1+(c=getchar());putchar(c<b|c>b+26?c:(c+s-b+26)%26+b))b=c<97?65:97;} Usage:$ ./caesar -1 <<< "123 a A z Z aBcDeFgHiKlMnOpQrStUvWxYz"
123 z Z y Y zAbCdEfGhJkLmNoPqRsTuVwXy

## k4, 80 bytes

The program accepts the shift number as a command-line argument and reads text from stdin.

Due to a technical constraint, negative shifts must be encoded with an underscore instead of a hyphen-minus. (Without the parser for interpreting this encoding, the solution would be 64 bytes.)

% wc -c c.k
80 c.k
% cat c.k
c:{x;,/x{y!(x_y),x#y}'.Qa`A}
.z.pi:{1@x^c[.q.mod[.*{x^((!).$"_-")x}.z.x]26]x;} % Here's the examples executed: % echo abcdefghijklmnopqrstuvwxyz|q c.k 1 bcdefghijklmnopqrstuvwxyza % echo 'Spam spam spam sausage and spam!'|q c.k 13 Fcnz fcnz fcnz fnhfntr naq fcnz! % echo abcdefghijklmnopqrstuvwxyz|q c.k 52 abcdefghijklmnopqrstuvwxyz % echo abcdefghijklmnopqrstuvwxyz|q c.k _1 zabcdefghijklmnopqrstuvwxy % echo ABCxyz|q c.k 3 DEFabc % And here's a silly little test harness that verifies both encode and decode. (This is zsh; for bash or ksh, change the for loop indexing to ((i=0;i<5;i++)). One-based arrays, ugh....) % a=(abcdefghijklmnopqrstuvwxyz 'Spam spam spam sausage and spam!' abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz ABCxyz) % b=(1 13 52 _1 3) % c=(bcdefghijklmnopqrstuvwxyza 'Fcnz fcnz fcnz fnhfntr naq fcnz!' abcdefghijklmnopqrstuvwxyz zabcdefghijklmnopqrstuvwxy DEFabc) % for ((i=1;i<=5;i++)) for> do for> r=$(echo "${a[i]}"|q c.k "${b[i]}")
for>     s=$(echo "$r"|if [[ ${b[i]} == _* ]]; then q c.k "${b[i]/_}"; else q c.k "_${b[i]}"; fi) for> printf '%s\t%s\n' "$([[ ${c[i]} ==$r ]] && echo good || echo bad)" "$([[${a[i]} == \$s ]] && echo good || echo bad)"
for> done
good    good
good    good
good    good
good    good
good    good
%

# Stax, 2 bytes

ç'

Run and debug it

• There's really no point in packing the source code. Mar 3 at 8:19
• it gets me funny points Mar 3 at 8:22