Caesar shift cipher
Introduction
What is the Caesar shift cipher (ROT$n$)? It's basically a cipher sequence that changes a letter's value from the number chosen. If we use ROT1 on "games", we get "hbnft". The basic interpretation of the cipher is iterating the value of a letter by 1 $n$ times. If you still don't understand, try using the ROT13 website.
Challenge
Make a program that takes input of a number from 1 to 25, call it $n$, and takes input of a string. It could be any. Then, use $n$ to convert the string into ROT$n$ and output the result.
Examples of inputs and outputs:
If $n = 4$ and string is "Hello, world.", we get Lipps, asvph
.
If $n = 15$ and string is "trololol", we get igdadada
.
If $n = 7$ and string is "gxoxk zhggt zbox rhn ni", we get never gonna give you up
.
If $n = 24$ and string is "I want breakfast!", we get G uylr zpcyidyqr!
.
If $n = 13$ and string is "guvf grkg vf fhf", we get this text is sus
.
Shortest program wins.
[JavaScript (Node.js)], 67 60 …
3y ago
[Ruby], 56 bytes -> …
3y ago
[Python 3.8 (pre-release)], 98 …
3y ago
[C (gcc)], 112 bytes Functi …
3y ago
Javascript (V8), 202 97 bytes …
3y ago
Python 3, 86 85 bytes The r …
2d ago
[Lean 4], 183 181 bytes ``` …
9d ago
[C (clang)], 161 bytes …
3y ago
[Haskell], 74 bytes …
3y ago
9 answers
You are accessing this answer with a direct link, so it's being shown above all other answers regardless of its score. You can return to the normal view.
Python 3, 86 85 bytes
The reasoning behind why this works is basically that 1. we can directly compare the ordinal values of characters (apparently) and 2. we only need that if a character is alphanumeric, then
'A' < '`' < 'a'which is very interesting to think about.
Also, if we have an expression of the form a+(b)<<c
or a+b<<c
, apparently Python interprets that as (a+b)<<c
, which is cool, but so weird.
Solution:
lambda m,k:''.join([c,chr((o:=2+('`'<c)<<5)+(ord(c)+k-o)%26)][c.isalpha()]for c in m)
Try it online! I set the link to Never expire
, but please notify me if the link doesn't work.
0 comment threads
JavaScript (Node.js), 67 60 bytes
o=>r=>Buffer(o).map(c=>c%32<26&c>64?(c%32+r)%26+c-c%32:c)+''
o=>r=> // Define a function taking o and r, and returning...
Buffer(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+r)%26+c-c%32 // Rot-n the character - Mod 32, add r, mod 26, add correct number depending on whether it's uppercase of lowercase.
:c) // Else return the original string
) + '' // Coerce to string
-7 thanks to Shaggy.
Ruby, 56 bytes
->s,i{a=[*?a..?z].rotate(i)*"";s.tr "A-Za-z",a.upcase+a}
tr
is wildly useful here. Builds the tr string manually and replaces only the alphabets.
0 comment threads
C (gcc), 112 bytes
Function solution.
p,*a;f(char*s,int n){a=strdup(s);for(s=a;*s;s++)(p=isalpha(*s)?(*s&96)^96?65:97:0)&&(*s=(*s-p+n)%26+p);puts(a);}
Explanation: The code takes a hard copy of the passed parameter and increases each character with the value, but only in case it's a letter.
isalpha determines if something is a letter, then *s & 0x60
masks out lower case, since those always have bits 0x60 set (and upper always have 0x40 but not 0x60).
For upper case, p gets set to 'A', for lower case it gets set to 'a', otherwise to zero. The equation to handle wrap-around *s=(*s-p+n)%26+p
only gets executed if p is not zero and basically just "modulo away" results larger than 26 - the size of the alphabet.
0 comment threads
Javascript (V8), 202 97 bytes
o=>r=>o.replace(/[a-zA-Z]/g,o=>String.fromCharCode((o<="Z"?90:122)>=(o=o.charCodeAt()+r)?o:o-26))
Since the text of input must be manually changed from the code, here is how to change it, Go to console.log(rot("Hello World")(4));
and change text between ""
(String) into anything you want lke console.log(rot("Codidact Code Golf)(4));
and if you want to change ROT$n$, change the number between brackets into anything like console.log(rot("Codidact Code Golf)(13));
.
4 comment threads
Python 3.8 (pre-release), 98 bytes
lambda s,n:''.join((c,chr((ord(c)+n-1-(o:=(64,96)[c.islower()]))%26+o+1))[c.isalpha()] for c in s)
C (clang), 161 bytes
i,j,k;main(){char *s;scanf("%i%[^\n]%*c",&i,s);for(j=0;j<strlen(s);j++){if(isalpha(s[j])){for(k=0;k<i;k++){if(s[j]==90||s[j]==122){s[j]-=26;}s[j]+=1;}}}puts(s);}
0 comment threads
Lean 4, 183 181 bytes
def c(t:String)(s:Nat):String:=t.map (λc=>if Char.isAlpha c then let b:=if Char.isLower c then 'a'else 'A';let h:=(Char.toNat c-Char.toNat b+s)%26+Char.toNat b;Char.ofNat h else c)
Honestly it's surprising that 1) you can just throw everything on one line, no matter the function's complexity, and 2) you can define anonymous functions inside of a function, which is something I did not know.
Hexdump since the source code contains unprintable characters:
00000000 64 65 66 20 63 28 74 3a 53 74 72 69 6e 67 29 28 |def c(t:String)(|
00000010 73 3a 4e 61 74 29 3a 53 74 72 69 6e 67 3a 3d 74 |s:Nat):String:=t|
00000020 2e 6d 61 70 20 28 ce bb 63 3d 3e 69 66 20 43 68 |.map (..c=>if Ch|
00000030 61 72 2e 69 73 41 6c 70 68 61 20 63 20 74 68 65 |ar.isAlpha c the|
00000040 6e 20 6c 65 74 20 62 3a 3d 69 66 20 43 68 61 72 |n let b:=if Char|
00000050 2e 69 73 4c 6f 77 65 72 20 63 20 74 68 65 6e 20 |.isLower c then |
00000060 27 61 27 65 6c 73 65 20 27 41 27 3b 6c 65 74 20 |'a'else 'A';let |
00000070 68 3a 3d 28 43 68 61 72 2e 74 6f 4e 61 74 20 63 |h:=(Char.toNat c|
00000080 2d 43 68 61 72 2e 74 6f 4e 61 74 20 62 2b 73 29 |-Char.toNat b+s)|
00000090 25 32 36 2b 43 68 61 72 2e 74 6f 4e 61 74 20 62 |%26+Char.toNat b|
000000a0 3b 43 68 61 72 2e 6f 66 4e 61 74 20 68 20 65 6c |;Char.ofNat h el|
000000b0 73 65 20 63 29 |se c)|
0 comment threads