Caesar cipher: Difference between revisions
(Update code to Astro0.1.14a/) |
(Applesoft BASIC) |
||
Line 193: | Line 193: | ||
</pre> |
</pre> |
||
=={{header|Applesoft BASIC}}== |
|||
<lang ApplesoftBasic>100 INPUT ""; T$ |
|||
110 LET K% = RND(1) * 25 + 1 |
|||
120 PRINT "ENCODED WITH "; |
|||
130 GOSUB 200ENCODED |
|||
140 LET K% = 26 - K% |
|||
150 PRINT "DECODED WITH "; |
|||
160 GOSUB 200DECODED |
|||
170 END |
|||
REM ENCODED/DECODED |
|||
200 PRINT "CAESAR " K%; |
|||
210 LET K$(1) = " (ROT-13)" |
|||
220 PRINT K$(K% = 13) |
|||
230 GOSUB 300CAESAR |
|||
240 PRINT T$ |
|||
250 RETURN |
|||
REM CAESAR T$ K% |
|||
300 FOR I = 1 TO LEN(T$) |
|||
310 LET C$ = MID$(T$, I, 1) |
|||
320 GOSUB 400ENCODE |
|||
330 LET L = I - 1 |
|||
340 LET T$(0) = MID$(T$, 1, L) |
|||
350 LET L = I + 1 |
|||
360 LET T$ = C$ + MID$(T$, L) |
|||
370 LET T$ = T$(0) + T$ |
|||
380 NEXT I |
|||
390 RETURN |
|||
REM ENCODE C$ K% |
|||
400 LET C = ASC(C$) |
|||
410 LET L = (C > 95) * 32 |
|||
420 LET C = C - L |
|||
430 IF C < 65 THEN RETURN |
|||
440 IF C > 90 THEN RETURN |
|||
450 LET C = C + K% |
|||
460 IF C > 90 THEN C = C - 26 |
|||
470 LET C$ = CHR$(C + L) |
|||
480 RETURN</lang> |
|||
{{out}}<pre>]RUN |
|||
The quick brown fox jumps over the lazy dog. |
|||
ENCODED WITH CAESAR 12 |
|||
Ftq cguow ndaiz raj vgybe ahqd ftq xmlk pas. |
|||
DECODED WITH CAESAR 14 |
|||
The quick brown fox jumps over the lazy dog. |
|||
]RUN |
|||
PACK MY BOX WITH FIVE DOZEN LIQUOR JUGS |
|||
ENCODED WITH CAESAR 13 (ROT-13) |
|||
CNPX ZL OBK JVGU SVIR QBMRA YVDHBE WHTF |
|||
DECODED WITH CAESAR 13 (ROT-13) |
|||
PACK MY BOX WITH FIVE DOZEN LIQUOR JUGS |
|||
]K%=1:GOTO120 |
|||
ENCODED WITH CAESAR 1 |
|||
QBDL NZ CPY XJUI GJWF EPAFO MJRVPS KVHT |
|||
DECODED WITH CAESAR 25 |
|||
PACK MY BOX WITH FIVE DOZEN LIQUOR JUGS</pre> |
|||
=={{header|Astro}}== |
=={{header|Astro}}== |
||
<lang python>fun caesar(s, k, decode: false): |
<lang python>fun caesar(s, k, decode: false): |
Revision as of 02:55, 16 January 2018
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Implement a Caesar cipher, both encoding and decoding.
The key is an integer from 1 to 25.
This cipher rotates (either towards left or right) the letters of the alphabet (A to Z).
The encoding replaces each letter with the 1st to 25th next letter in the alphabet (wrapping Z to A).
So key 2 encrypts "HI" to "JK", but key 20 encrypts "HI" to "BC".
This simple "mono-alphabetic substitution cipher" provides almost no security, because an attacker who has the encoded message can either use frequency analysis to guess the key, or just try all 25 keys.
Caesar cipher is identical to Vigenère cipher with a key of length 1.
Also, Rot-13 is identical to Caesar cipher with key 13.
- Related tasks
8th
<lang forth>\ Ensure the output char is in the correct range:
- modulate \ char base -- char
tuck n:- 26 n:+ 26 n:mod n:+ ;
\ Symmetric Caesar cipher. Input is text and number of characters to advance \ (or retreat, if negative). That value should be in the range 1..26
- caesar \ intext key -- outext
>r ( \ Ignore anything below '.' as punctuation: dup '. n:> if \ Do the conversion dup r@ n:+ swap \ Wrap appropriately 'A 'Z between if 'A else 'a then modulate then ) s:map rdrop ;
"The five boxing wizards jump quickly!" dup . cr 1 caesar dup . cr -1 caesar . cr bye</lang>
- Output:
The five boxing wizards jump quickly! Uif gjwf cpyjoh xjabset kvnq rvjdlmz! The five boxing wizards jump quickly!
Ada
<lang Ada>with Ada.Text_IO;
procedure Caesar is
type M26 is mod 26;
function To_M26(C: Character; Offset: Character) return M26 is begin return M26(Character'Pos(C)-Character'Pos(Offset)); end To_M26;
function To_Character(Value: in M26; Offset: Character) return Character is begin return Character'Val(Integer(Value)+Character'Pos(Offset)); end To_Character;
function Encrypt (Plain: String; Key: M26) return String is Ciph: String(Plain'Range);
begin for I in Plain'Range loop case Plain(I) is when 'A' .. 'Z' => Ciph(I) := To_Character(To_M26(Plain(I), 'A')+Key, 'A'); when 'a' .. 'z' => Ciph(I) := To_Character(To_M26(Plain(I), 'a')+Key, 'a'); when others => Ciph(I) := Plain(I); end case; end loop; return Ciph; end Encrypt;
Text: String := Ada.Text_IO.Get_Line; Key: M26 := 3; -- Default key from "Commentarii de Bello Gallico"
begin -- Caesar main program
Ada.Text_IO.Put_Line("Plaintext ------------>" & Text); Text := Encrypt(Text, Key); Ada.Text_IO.Put_Line("Ciphertext ----------->" & Text); Ada.Text_IO.Put_Line("Decrypted Ciphertext ->" & Encrypt(Text, -Key));
end Caesar;</lang>
- Output:
> ./caesar The five boxing wizards jump quickly Plaintext ------------>The five boxing wizards jump quickly Ciphertext ----------->Wkh ilyh eralqj zlcdugv mxps txlfnob Decrypted Ciphertext ->The five boxing wizards jump quickly
ALGOL 68
<lang algol68>#!/usr/local/bin/a68g --script #
program caesar: BEGIN
MODE MODXXVI = SHORT SHORT INT; # MOD26 #
PROC to m26 = (CHAR c, offset)MODXXVI: BEGIN ABS c - ABS offset END #to m26#;
PROC to char = (MODXXVI value, CHAR offset)CHAR: BEGIN REPR ( ABS offset + value MOD 26 ) END #to char#;
PROC encrypt = (STRING plain, MODXXVI key)STRING: BEGIN [UPB plain]CHAR ciph; FOR i TO UPB plain DO CHAR c = plain[i]; ciph[i]:= IF "A" <= c AND c <= "Z" THEN to char(to m26(c, "A")+key, "A") ELIF "a" <= c AND c <= "z" THEN to char(to m26(c, "a")+key, "a") ELSE c FI OD; ciph END #encrypt#;
- caesar main program #
STRING text := "The five boxing wizards jump quickly" # OR read string #; MODXXVI key := 3; # Default key from "Bello Gallico" #
printf(($gl$, "Plaintext ------------>" + text)); text := encrypt(text, key); printf(($gl$, "Ciphertext ----------->" + text)); printf(($gl$, "Decrypted Ciphertext ->" + encrypt(text, -key)))
END #caesar#</lang>
- Output:
Plaintext ------------>The five boxing wizards jump quickly Ciphertext ----------->Wkh ilyh eralqj zlcdugv mxps txlfnob Decrypted Ciphertext ->The five boxing wizards jump quickly
APL
<lang apl>
∇CAESAR[⎕]∇ ∇
[0] A←K CAESAR V [1] A←'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz' [2] ((,V∊A)/,V)←A[⎕IO+52|(2×K)+((A⍳,V)-⎕IO)~52] [3] A←V
∇
</lang>
- Output:
6 CAESAR ⎕←TEXT_MATRIX This method uses selective specification (similar to pattern matching in Haskell) to modify only alphabetic characters. Znoy skznuj ayky ykrkizobk yvkioloigzout (yosorgx zu vgzzkxt sgzinotm ot Ngyqkrr) zu sujole utre grvnghkzoi ingxgizkxy. ¯1 CAESAR ⎕←ENCRYPTED Ofhbujwf lfzt (efdszqujoh) xpslt: IBM 9000 Negative keys (decrypting) works: HAL 9000 ¯1.5 CAESAR ⎕←CAPSLOCK fUN FACT: FRACTIONAL KEYS SWITCH FROM upper case TO LOWER CASE. Esl dyar: dpyargmlyj icwq qugraf dpmk TOODQ BZRD rm jmucp ayqc.
Applesoft BASIC
<lang ApplesoftBasic>100 INPUT ""; T$
110 LET K% = RND(1) * 25 + 1 120 PRINT "ENCODED WITH "; 130 GOSUB 200ENCODED
140 LET K% = 26 - K% 150 PRINT "DECODED WITH "; 160 GOSUB 200DECODED
170 END
REM ENCODED/DECODED 200 PRINT "CAESAR " K%; 210 LET K$(1) = " (ROT-13)" 220 PRINT K$(K% = 13) 230 GOSUB 300CAESAR 240 PRINT T$ 250 RETURN
REM CAESAR T$ K% 300 FOR I = 1 TO LEN(T$) 310 LET C$ = MID$(T$, I, 1) 320 GOSUB 400ENCODE 330 LET L = I - 1 340 LET T$(0) = MID$(T$, 1, L) 350 LET L = I + 1 360 LET T$ = C$ + MID$(T$, L) 370 LET T$ = T$(0) + T$ 380 NEXT I 390 RETURN
REM ENCODE C$ K% 400 LET C = ASC(C$) 410 LET L = (C > 95) * 32 420 LET C = C - L 430 IF C < 65 THEN RETURN 440 IF C > 90 THEN RETURN 450 LET C = C + K% 460 IF C > 90 THEN C = C - 26 470 LET C$ = CHR$(C + L) 480 RETURN</lang>
- Output:
]RUNThe quick brown fox jumps over the lazy dog. ENCODED WITH CAESAR 12 Ftq cguow ndaiz raj vgybe ahqd ftq xmlk pas. DECODED WITH CAESAR 14 The quick brown fox jumps over the lazy dog.
]RUN PACK MY BOX WITH FIVE DOZEN LIQUOR JUGS ENCODED WITH CAESAR 13 (ROT-13) CNPX ZL OBK JVGU SVIR QBMRA YVDHBE WHTF DECODED WITH CAESAR 13 (ROT-13) PACK MY BOX WITH FIVE DOZEN LIQUOR JUGS
]K%=1:GOTO120 ENCODED WITH CAESAR 1 QBDL NZ CPY XJUI GJWF EPAFO MJRVPS KVHT DECODED WITH CAESAR 25
PACK MY BOX WITH FIVE DOZEN LIQUOR JUGS
Astro
<lang python>fun caesar(s, k, decode: false):
if decode: k = 26 - k join(char((ord(c) - 65 + k) mod 26 + 65) | c in s.upper() where "a" <= c <= "A")
let msg = "The quick brown fox jumped over the lazy dogs" print msg let enc = caesar(msg, 11) print _.(enc) _.(caesar(enc, 11, decode: true)) </lang>
AutoHotkey
This ungodly solution is an attempt at code-golf. It requires input to be all-caps alphabetic, only works on AutoHotkey_L Unicode, and might not run on x64 <lang AutoHotkey>n=2 s=HI t:=&s While *t o.=Chr(Mod(*t-65+n,26)+65),t+=2 MsgBox % o</lang> This next one is much more sane and handles input very well, including case. <lang AutoHotkey>Caesar(string, n){ Loop Parse, string { If (Asc(A_LoopField) >= Asc("A") and Asc(A_LoopField) <= Asc("Z")) out .= Chr(Mod(Asc(A_LoopField)-Asc("A")+n,26)+Asc("A")) Else If (Asc(A_LoopField) >= Asc("a") and Asc(A_LoopField) <= Asc("z")) out .= Chr(Mod(Asc(A_LoopField)-Asc("a")+n,26)+Asc("a")) Else out .= A_LoopField } return out }
MsgBox % Caesar("h i", 2) "`n" Caesar("Hi", 20)</lang>
- Output:
j k Bc
AutoIt
The Ceasar Funktion can enrcypt and decrypt, standart is Encryption, to Decrypt set third parameter to False <lang autoit> $Caesar = Caesar("Hi", 2, True) MsgBox(0, "Caesar", $Caesar) Func Caesar($String, $int, $encrypt = True) If Not IsNumber($int) Or Not StringIsDigit($int) Then Return SetError(1, 0, 0) If $int < 1 Or $int > 25 Then Return SetError(2, 0, 0) Local $sLetters, $x $String = StringUpper($String) $split = StringSplit($String, "") For $i = 1 To $split[0] If Asc($split[$i]) - 64 > 26 Or Asc($split[$i]) - 64 < 1 Then $sLetters &= $split[$i] ContinueLoop EndIf If $encrypt = True Then $move = Asc($split[$i]) - 64 + $int Else $move = Asc($split[$i]) - 64 - $int EndIf If $move > 26 Then $move -= 26 ElseIf $move < 1 Then $move += 26 EndIf While $move $x = Mod($move, 26) If $x = 0 Then $x = 26 $sLetters &= Chr($x + 64) $move = ($move - $x) / 26 WEnd Next Return $sLetters EndFunc ;==>Caesar </lang>
AWK
<lang awk>
- !/usr/bin/awk -f
BEGIN {
message = "My hovercraft is full of eels." key = 1
cypher = caesarEncode(key, message) clear = caesarDecode(key, cypher)
print "message: " message print " cypher: " cypher print " clear: " clear exit
}
function caesarEncode(key, message) {
return caesarXlat(key, message, "encode")
}
function caesarDecode(key, message) {
return caesarXlat(key, message, "decode")
}
function caesarXlat(key, message, dir, plain, cypher, i, num, s) {
plain = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" cypher = substr(plain, key+1) substr(plain, 1, key)
if (toupper(substr(dir, 1, 1)) == "D") { s = plain plain = cypher cypher = s }
s = "" message = toupper(message) for (i = 1; i <= length(message); i++) { num = index(plain, substr(message, i, 1)) if (num) s = s substr(cypher, num, 1) else s = s substr(message, i, 1) } return s
} </lang>
- Output:
message: My hovercraft is full of eels. cypher: NZ IPWFSDSBGU JT GVMM PG FFMT. clear: MY HOVERCRAFT IS FULL OF EELS.
Babel
<lang babel>((main
{"The quick brown fox jumps over the lazy dog.\n" dup <<
17 caesar_enc ! dup <<
17 caesar_dec ! <<})
(caesar_enc
{ 2 take { caesar_enc_loop ! } nest })
(caesar_enc_loop {
give <- str2ar {({ dup is_upper ! } { 0x40 - -> dup <- encrypt ! 0x40 + } { dup is_lower ! } { 0x60 - -> dup <- encrypt ! 0x60 + } { 1 } {fnord}) cond} eachar collect ! ls2lf ar2str})
(collect { -1 take })
(encrypt { + 1 - 26 % 1 + })
(caesar_dec { <- 26 -> - caesar_enc ! })
(is_upper
{ dup <- 0x40 cugt -> 0x5b cult cand })
(is_lower
{ dup <- 0x60 cugt -> 0x7b cult cand }))</lang>
- Output:
The quick brown fox jumps over the lazy dog. Kyv hlztb sifne wfo aldgj fmvi kyv crqp ufx. The quick brown fox jumps over the lazy dog.
BaCon
<lang qbasic>CONST lc$ = "abcdefghijklmnopqrstuvwxyz" CONST uc$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
CONST txt$ = "The quick brown fox jumps over the lazy dog."
FUNCTION Ceasar$(t$, k)
lk$ = MID$(lc$ & lc$, k+1, 26) uk$ = MID$(uc$ & uc$, k+1, 26)
RETURN REPLACE$(t$, lc$ & uc$, lk$ & uk$, 2)
END FUNCTION
tokey = RANDOM(25)+1 PRINT "Encrypting text with key: ", tokey
en$ = Ceasar$(txt$, tokey)
PRINT "Encrypted: ", en$ PRINT "Decrypted: ", Ceasar$(en$, 26-tokey)</lang>
- Output:
user@host $ bacon ceasar Converting 'ceasar.bac'... done, 20 lines were processed in 0.015 seconds. Compiling 'ceasar.bac'... cc -c ceasar.bac.c cc -o ceasar ceasar.bac.o -lbacon -lm Done, program 'ceasar' ready. user@host $ ./ceasar Encrypting text with key: 23 Encrypted: Qeb nrfzh yoltk clu grjmp lsbo qeb ixwv ald. Decrypted: The quick brown fox jumps over the lazy dog.
BBC BASIC
<lang bbcbasic> plaintext$ = "Pack my box with five dozen liquor jugs"
PRINT plaintext$ key% = RND(25) cyphertext$ = FNcaesar(plaintext$, key%) PRINT cyphertext$ decyphered$ = FNcaesar(cyphertext$, 26-key%) PRINT decyphered$ END DEF FNcaesar(text$, key%) LOCAL I%, C% FOR I% = 1 TO LEN(text$) C% = ASC(MID$(text$,I%)) IF (C% AND &1F) >= 1 AND (C% AND &1F) <= 26 THEN C% = (C% AND &E0) OR (((C% AND &1F) + key% - 1) MOD 26 + 1) MID$(text$, I%, 1) = CHR$(C%) ENDIF NEXT = text$
</lang>
- Output:
Pack my box with five dozen liquor jugs Zkmu wi lyh gsdr psfo nyjox vsaeyb teqc Pack my box with five dozen liquor jugs
Befunge
Almost direct copy of the Vigenère cipher, although the code has been reversed and the first line eliminated because of the simpler key initialisation.
The text to encrypt is read from stdin, and the key is the first integer on the stack - 11 (65+) in the example below.
<lang befunge>65+>>>>10p100p1>:v:+>#*,#g1#0-#0:#!<< "`"::_@#!`\*84:<~<$<^+"A"%*2+9<v"{"\`
- -"A"-::0\`\55*`+#^_\0g+"4"+4^>\`*48</lang>
- Output:
The quick brown fox jumped over the lazy dogs ESPBFTNVMCZHYQZIUFXAPOZGPCESPWLKJOZRD
The decrypter is essentially identical, except for a change of sign on the last line.
<lang befunge>65+>>>>10p100p1>:v:+>#*,#g1#0-#0:#!<< "`"::_@#!`\*84:<~<$<^+"A"%*2+9<v"{"\`
- -"A"-::0\`\55*`+#^_\0g-"4"+4^>\`*48</lang>
- Output:
ESPBFTNVMCZHYQZIUFXAPOZGPCESPWLKJOZRD THEQUICKBROWNFOXJUMPEDOVERTHELAZYDOGS
C
<lang c>#include <stdio.h>
- include <stdlib.h>
- include <string.h>
- define caesar(x) rot(13, x)
- define decaesar(x) rot(13, x)
- define decrypt_rot(x, y) rot((26-x), y)
void rot(int c, char *str) { int l = strlen(str); const char *alpha[2] = { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
int i; for (i = 0; i < l; i++) { if (!isalpha(str[i])) continue;
str[i] = alpha[isupper(str[i])][((int)(tolower(str[i])-'a')+c)%26]; } }
int main()
{
char str[] = "This is a top secret text message!";
printf("Original: %s\n", str); caesar(str); printf("Encrypted: %s\n", str); decaesar(str); printf("Decrypted: %s\n", str);
return 0; }</lang>
C++
<lang Cpp>#include <string>
- include <iostream>
- include <algorithm>
- include <cctype>
class MyTransform { private :
int shift ;
public :
MyTransform( int s ) : shift( s ) { }
char operator( )( char c ) { if ( isspace( c ) )
return ' ' ;
else {
static std::string letters( "abcdefghijklmnopqrstuvwxyz" ) ; std::string::size_type found = letters.find(tolower( c )) ; int shiftedpos = ( static_cast<int>( found ) + shift ) % 26 ; if ( shiftedpos < 0 ) //in case of decryption possibly shiftedpos = 26 + shiftedpos ; char shifted = letters[shiftedpos] ; return shifted ;
} }
} ;
int main( ) {
std::string input ; std::cout << "Which text is to be encrypted ?\n" ; getline( std::cin , input ) ; std::cout << "shift ?\n" ; int myshift = 0 ; std::cin >> myshift ; std::cout << "Before encryption:\n" << input << std::endl ; std::transform ( input.begin( ) , input.end( ) , input.begin( ) ,
MyTransform( myshift ) ) ;
std::cout << "encrypted:\n" ; std::cout << input << std::endl ; myshift *= -1 ; //decrypting again std::transform ( input.begin( ) , input.end( ) , input.begin( ) ,
MyTransform( myshift ) ) ;
std::cout << "Decrypted again:\n" ; std::cout << input << std::endl ; return 0 ;
}</lang>
- Output:
Which text is to be encrypted ? this is an interesting text shift ? 3 Before encryption: this is an interesting text encrypted: wklv lv dq lqwhuhvwlqj whaw Decrypted again: this is an interesting text
Alternative version - lambda functions, auto, iterators
<lang Cpp>/* caesar cipher */
- include <string>
- include <iostream>
- include <cctype>
int main( ) {
using namespace std;
string input ; int key = 0;
// lambda functions
auto encrypt = [&](char c, int key ) { char A = ( islower(c) )? 'a': 'A'; c = (isalpha(c))? (c - A + key) % 26 + A : c; return (char) c; };
auto decrypt = [&](char c, int key ) { char A = ( islower(c) )? 'a': 'A'; c = (isalpha(c))? (c - A + (26 - key) ) % 26 + A : c; return (char) c; };
cout << "Enter a line of text.\n"; getline( cin , input );
cout << "Enter an integer to shift text.\n"; cin >> key; while ( (key < 1) || (key > 25) ) { cout << "must be an integer between 1 and 25 -->" << endl; cin >> key; }
cout << "Plain: \t" << input << endl ;
for ( auto & cp : input) // use & for mutability cp = encrypt(cp, key);
cout << "Encrypted:\t" << input << endl;
for ( auto & cp : input) cp = decrypt(cp, key);
cout << "Decrypted:\t" << input << endl;
return 0 ;
} </lang>
- Output:
Enter a line of text. This is a line of plain text, 50 characters long. Enter an integer to shift text. 5 Plain: This is a line of plain text, 50 characters long. Encrypted: Ymnx nx f qnsj tk uqfns yj}y1 :5 hmfwfhyjwx qtsl3 Decrypted: This is a line of plain text, 50 characters long.
C#
<lang csharp>using System; using System.Linq;
namespace CaesarCypher {
class Program { static char Encrypt(char ch, int code) { if (!char.IsLetter(ch)) return ch;
char offset = char.IsUpper(ch) ? 'A' : 'a'; return (char)((ch + code - offset) % 26 + offset); }
static string Encrypt(string input, int code) { return new string(input.Select(ch => Encrypt(ch, code)).ToArray()); }
static string Decrypt(string input, int code) { return Encrypt(input, 26 - code); }
const string TestCase = "Pack my box with five dozen liquor jugs.";
static void Main() { string str = TestCase;
Console.WriteLine(str); str = Encrypt(str, 5); Console.WriteLine("Encrypted: " + str); str = Decrypt(str, 5); Console.WriteLine("Decrypted: " + str); Console.ReadKey(); } }
}</lang>
- Output:
Pack my box with five dozen liquor jugs. Encrypted: Ufhp rd gtc bnym knaj itejs qnvztw ozlx. Decrypted: Pack my box with five dozen liquor jugs.
Clojure
<lang Clojure>(defn encrypt-character [offset c]
(if (Character/isLetter c) (let [v (int c) base (if (>= v (int \a)) (int \a) (int \A)) offset (mod offset 26)] ;works with negative offsets too! (char (+ (mod (+ (- v base) offset) 26) base))) c))
(defn encrypt [offset text]
(apply str (map #(encrypt-character offset %) text)))
(defn decrypt [offset text]
(encrypt (- 26 offset) text))
(let [text "The Quick Brown Fox Jumps Over The Lazy Dog."
enc (encrypt -1 text)] (print "Original text:" text "\n") (print "Encryption:" enc "\n") (print "Decryption:" (decrypt -1 enc) "\n"))</lang>
- Output:
Original text: The Quick Brown Fox Jumps Over The Lazy Dog. Encryption: Sgd Pthbj Aqnvm Enw Itlor Nudq Sgd Kzyx Cnf. Decryption: The Quick Brown Fox Jumps Over The Lazy Dog.
COBOL
COBOL-85 ASCII or EBCIDIC <lang COBOL>
identification division. program-id. caesar. data division. 1 msg pic x(50) value "The quick brown fox jumped over the lazy dog.". 1 offset binary pic 9(4) value 7. 1 from-chars pic x(52). 1 to-chars pic x(52). 1 tabl. 2 pic x(26) value "abcdefghijklmnopqrstuvwxyz". 2 pic x(26) value "ABCDEFGHIJKLMNOPQRSTUVWXYZ". 2 pic x(26) value "abcdefghijklmnopqrstuvwxyz". 2 pic x(26) value "ABCDEFGHIJKLMNOPQRSTUVWXYZ". procedure division. begin. display msg perform encrypt display msg perform decrypt display msg stop run .
encrypt. move tabl (1:52) to from-chars move tabl (1 + offset:52) to to-chars inspect msg converting from-chars to to-chars .
decrypt. move tabl (1 + offset:52) to from-chars move tabl (1:52) to to-chars inspect msg converting from-chars to to-chars . end program caesar.
</lang>
- Output:
The quick brown fox jumped over the lazy dog. aol xBpjr iyvDu mvE qBtwlk vCly Aol shGF kvn. The quick brown fox jumped over the lazy dog.
<lang cobol> >>SOURCE FORMAT IS FREE PROGRAM-ID. caesar-cipher.
ENVIRONMENT DIVISION. CONFIGURATION SECTION. REPOSITORY.
FUNCTION encrypt FUNCTION decrypt .
DATA DIVISION. WORKING-STORAGE SECTION. 01 plaintext PIC X(50). 01 offset PIC 99.
01 encrypted-str PIC X(50).
PROCEDURE DIVISION.
DISPLAY "Enter a message to encrypt: " NO ADVANCING ACCEPT plaintext DISPLAY "Enter the amount to shift by: " NO ADVANCING ACCEPT offset
MOVE FUNCTION encrypt(offset, plaintext) TO encrypted-str DISPLAY "Encrypted: " encrypted-str DISPLAY "Decrypted: " FUNCTION decrypt(offset, encrypted-str) .
END PROGRAM caesar-cipher.
FUNCTION-ID. encrypt.
DATA DIVISION. LOCAL-STORAGE SECTION. 01 i PIC 9(3).
01 a PIC 9(3).
LINKAGE SECTION. 01 offset PIC 99. 01 str PIC X(50).
01 encrypted-str PIC X(50).
PROCEDURE DIVISION USING offset, str RETURNING encrypted-str.
MOVE str TO encrypted-str PERFORM VARYING i FROM 1 BY 1 UNTIL i > FUNCTION LENGTH(str) IF encrypted-str (i:1) IS NOT ALPHABETIC OR encrypted-str (i:1) = SPACE EXIT PERFORM CYCLE END-IF
IF encrypted-str (i:1) IS ALPHABETIC-UPPER MOVE FUNCTION ORD("A") TO a ELSE MOVE FUNCTION ORD("a") TO a END-IF
MOVE FUNCTION CHAR(FUNCTION MOD(FUNCTION ORD(encrypted-str (i:1)) - a + offset, 26) + a) TO encrypted-str (i:1) END-PERFORM .
END FUNCTION encrypt.
FUNCTION-ID. decrypt.
ENVIRONMENT DIVISION. CONFIGURATION SECTION. REPOSITORY.
FUNCTION encrypt .
DATA DIVISION. LOCAL-STORAGE SECTION. 01 decrypt-offset PIC 99.
LINKAGE SECTION. 01 offset PIC 99. 01 str PIC X(50).
01 decrypted-str PIC X(50).
PROCEDURE DIVISION USING offset, str RETURNING decrypted-str.
SUBTRACT 26 FROM offset GIVING decrypt-offset MOVE FUNCTION encrypt(decrypt-offset, str) TO decrypted-str .
END FUNCTION decrypt.</lang>
- Output:
Enter a message to encrypt: The quick brown fox jumps over the lazy dog. Enter the amount to shift by: 7 Encrypted: Aol xbpjr iyvdu mve qbtwz vcly aol shgf kvn. Decrypted: The quick brown fox jumps over the lazy dog.
CoffeeScript
<lang coffeescript>cipher = (msg, rot) ->
msg.replace /([a-z|A-Z])/g, ($1) -> c = $1.charCodeAt(0) String.fromCharCode \ if c >= 97 then (c + rot + 26 - 97) % 26 + 97 else (c + rot + 26 - 65) % 26 + 65
console.log cipher "Hello World", 2 console.log cipher "azAz %^&*()", 3</lang>
- Output:
> coffee foo.coffee Jgnnq Yqtnf dcDc %^&*()
Common Lisp
<lang lisp>(defun encipher-char (ch key)
(let* ((c (char-code ch)) (la (char-code #\a)) (ua (char-code #\A)) (base (cond ((<= la c (char-code #\z)) la) ((<= ua c (char-code #\Z)) ua) (nil)))) (if base (code-char (+ (mod (+ (- c base) key) 26) base)) ch)))
(defun caesar-cipher (str key)
(map 'string #'(lambda (c) (encipher-char c key)) str))
(defun caesar-decipher (str key) (caesar-cipher str (- key)))
(let* ((original-text "The five boxing wizards jump quickly")
(key 3) (cipher-text (caesar-cipher original-text key)) (recovered-text (caesar-decipher cipher-text key))) (format t " Original: ~a ~%" original-text) (format t "Encrypted: ~a ~%" cipher-text) (format t "Decrypted: ~a ~%" recovered-text))</lang>
- Output:
Original: The five boxing wizards jump quickly Encrypted: Wkh ilyh eralqj zlcdugv mxps txlfnob Decrypted: The five boxing wizards jump quickly
Crystal
<lang crystal>class String
ALPHABET = ("A".."Z").to_a
def caesar_cipher(num) self.tr(ALPHABET.join, ALPHABET.rotate(num).join) end
end
- demo
encrypted = "THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG".caesar_cipher(5) decrypted = encrypted.caesar_cipher(-5) </lang>
Cubescript
<lang cubescript>alias modn [ mod (+ (mod $arg1 $arg2) $arg2) $arg2 ] //Cubescript's built-in mod will fail on negative numbers
alias cipher [ push alpha [ "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z" "a b c d e f g h i j k l m n o p q r s t u v w x y z" ] [ push chars [] [ loop i (strlen $arg1) [ looplist n $alpha [ if (! (listlen $chars)) [ alias chars (? (> (listindex $n (substr $arg1 $i 1)) -1) $n []) ] ] alias arg1 ( concatword (substr $arg1 0 $i) ( ? (> (listindex $chars (substr $arg1 $i 1)) -1) ( at $chars ( modn (+ ( listindex $chars (substr $arg1 $i 1) ) $arg2) (listlen $chars) ) ) (substr $arg1 $i 1) ) (substr $arg1 (+ $i 1) (strlen $arg1)) ) alias chars [] ] ] ] result $arg1 ]
alias decipher [ push alpha [ "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z" "a b c d e f g h i j k l m n o p q r s t u v w x y z" ] [ push chars [] [ loop i (strlen $arg1) [ looplist n $alpha [ if (! (listlen $chars)) [ alias chars (? (> (listindex $n (substr $arg1 $i 1)) -1) $n []) ] ] alias arg1 ( concatword (substr $arg1 0 $i) ( ? (> (listindex $chars (substr $arg1 $i 1)) -1) ( at $chars ( modn (- ( listindex $chars (substr $arg1 $i 1) ) $arg2 ) (listlen $chars) ) ) (substr $arg1 $i 1) ) (substr $arg1 (+ $i 1) (strlen $arg1)) ) alias chars [] ] ] ] result $arg1 ]</lang>
Usage: <lang>>>> cipher "The Quick Brown Fox Jumps Over The Lazy Dog." 5 > Ymj Vznhp Gwtbs Ktc Ozrux Tajw Ymj Qfed Itl. >>> decipher "Ymj Vznhp Gwtbs Ktc Ozrux Tajw Ymj Qfed Itl." 5 > The Quick Brown Fox Jumps Over The Lazy Dog.</lang>
D
<lang d>import std.stdio, std.traits;
S rot(S)(in S s, in int key) pure nothrow @safe if (isSomeString!S) {
auto res = s.dup;
foreach (immutable i, ref c; res) { if ('a' <= c && c <= 'z') c = ((c - 'a' + key) % 26 + 'a'); else if ('A' <= c && c <= 'Z') c = ((c - 'A' + key) % 26 + 'A'); } return res;
}
void main() @safe {
enum key = 3; immutable txt = "The five boxing wizards jump quickly"; writeln("Original: ", txt); writeln("Encrypted: ", txt.rot(key)); writeln("Decrypted: ", txt.rot(key).rot(26 - key));
}</lang>
- Output:
Original: The five boxing wizards jump quickly Encrypted: Wkh ilyh eralqj zlcdugv mxps txlfnob Decrypted: The five boxing wizards jump quickly
Simpler in-place version (same output): <lang d>import std.stdio, std.ascii;
void inplaceRot(char[] txt, in int key) pure nothrow {
foreach (ref c; txt) { if (isLower(c)) c = (c - 'a' + key) % 26 + 'a'; else if (isUpper(c)) c = (c - 'A' + key) % 26 + 'A'; }
}
void main() {
enum key = 3; auto txt = "The five boxing wizards jump quickly".dup; writeln("Original: ", txt); txt.inplaceRot(key); writeln("Encrypted: ", txt); txt.inplaceRot(26 - key); writeln("Decrypted: ", txt);
}</lang>
A version that uses the standard library (same output): <lang d>import std.stdio, std.ascii, std.string, std.algorithm;
string rot(in string s, in int key) pure nothrow @safe {
auto uppr = uppercase.dup.representation; bringToFront(uppr[0 .. key], uppr[key .. $]); auto lowr = lowercase.dup.representation; bringToFront(lowr[0 .. key], lowr[key .. $]); return s.translate(makeTrans(letters, assumeUTF(uppr ~ lowr)));
}
void main() {
enum key = 3; immutable txt = "The five boxing wizards jump quickly"; writeln("Original: ", txt); writeln("Encrypted: ", txt.rot(key)); writeln("Decrypted: ", txt.rot(key).rot(26 - key));
}</lang>
Dart
<lang dart>class Caesar {
int _key;
Caesar(this._key);
int _toCharCode(String s) { return s.charCodeAt(0); }
String _fromCharCode(int ch) { return new String.fromCharCodes([ch]); }
String _process(String msg, int offset) { StringBuffer sb=new StringBuffer(); for(int i=0;i<msg.length;i++) { int ch=msg.charCodeAt(i); if(ch>=_toCharCode('A')&&ch<=_toCharCode('Z')) { sb.add(_fromCharCode(_toCharCode("A")+(ch-_toCharCode("A")+offset)%26)); } else if(ch>=_toCharCode('a')&&ch<=_toCharCode('z')) { sb.add(_fromCharCode(_toCharCode("a")+(ch-_toCharCode("a")+offset)%26)); } else { sb.add(msg[i]); } } return sb.toString(); }
String encrypt(String msg) { return _process(msg, _key); }
String decrypt(String msg) { return _process(msg, 26-_key); }
}
void trip(String msg) {
Caesar cipher=new Caesar(10);
String enc=cipher.encrypt(msg); String dec=cipher.decrypt(enc); print("\"$msg\" encrypts to:"); print("\"$enc\" decrypts to:"); print("\"$dec\""); Expect.equals(msg,dec);
}
main() {
Caesar c2=new Caesar(2); print(c2.encrypt("HI")); Caesar c20=new Caesar(20); print(c20.encrypt("HI"));
// try a few roundtrips
trip(""); trip("A"); trip("z"); trip("Caesar cipher"); trip(".-:/\"\\!"); trip("The Quick Brown Fox Jumps Over The Lazy Dog.");
}</lang>
- Output:
JK BC "" encrypts to: "" decrypts to: "" "A" encrypts to: "K" decrypts to: "A" "z" encrypts to: "j" decrypts to: "z" "Caesar cipher" encrypts to: "Mkockb mszrob" decrypts to: "Caesar cipher" ".-:/"\!" encrypts to: ".-:/"\!" decrypts to: ".-:/"\!" "The Quick Brown Fox Jumps Over The Lazy Dog." encrypts to: "Dro Aesmu Lbygx Pyh Tewzc Yfob Dro Vkji Nyq." decrypts to: "The Quick Brown Fox Jumps Over The Lazy Dog."
Eiffel
<lang eiffel> class APPLICATION
inherit ARGUMENTS
create make
feature {NONE} -- Initialization
make -- Run application. local s: STRING_32 do s := "The tiny tiger totally taunted the tall Till." print ("%NString to encode: " + s) print ("%NEncoded string: " + encode (s, 12)) print ("%NDecoded string (after encoding and decoding): " + decode (encode (s, 12), 12)) end
feature -- Basic operations
decode (to_be_decoded: STRING_32; offset: INTEGER): STRING_32 -- Decode `to be decoded' according to `offset'. do Result := encode (to_be_decoded, 26 - offset) end
encode (to_be_encoded: STRING_32; offset: INTEGER): STRING_32 -- Encode `to be encoded' according to `offset'. local l_offset: INTEGER l_char_code: INTEGER do create Result.make_empty l_offset := (offset \\ 26) + 26 across to_be_encoded as tbe loop if tbe.item.is_alpha then if tbe.item.is_upper then l_char_code := ('A').code + (tbe.item.code - ('A').code + l_offset) \\ 26 Result.append_character (l_char_code.to_character_32) else l_char_code := ('a').code + (tbe.item.code - ('a').code + l_offset) \\ 26 Result.append_character (l_char_code.to_character_32) end else Result.append_character (tbe.item) end end end end </lang>
- Output:
String to encode: The tiny tiger totally taunted the tall Till. Encoded string: Ftq fuzk fusqd fafmxxk fmgzfqp ftq fmxx Fuxx. Decoded string (after encoding and decoding): The tiny tiger totally taunted the tall Till.
Ela
<lang ela>open number char monad io string
chars = "ABCDEFGHIJKLMOPQRSTUVWXYZ"
caesar _ _ [] = "" caesar op key (x::xs) = check shifted ++ caesar op key xs
where orig = indexOf (string.upper $ toString x) chars shifted = orig `op` key check val | orig == -1 = x | val > 24 = trans $ val - 25 | val < 0 = trans $ 25 + val | else = trans shifted trans idx = chars:idx
cypher = caesar (+) decypher = caesar (-)
key = 2
do
putStrLn "A string to encode:" str <- readStr putStr "Encoded string: " cstr <- return <| cypher key str put cstr putStrLn "" putStr "Decoded string: " put $ decypher key cstr</lang>
- Output:
A string to encode: HELLO! THIS IS A SECRET MESSAGE! Encoded string: "JGOOQ! VJKU KU C UGETGV PGUUCIG!" Decoded string: "HELLO! THIS IS A SECRET MESSAGE!"
Elena
ELENA 3.2 : <lang elena>import system'routines. import system'math. import extensions.
const Letters = "abcdefghijklmnopqrstuvwxyz". const BigLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ". const TestText = "Pack my box with five dozen liquor jugs.". const Key = 12.
class Encrypting :: Enumerator {
object theKey. object theEnumerator. constructor new key:aKey text:aText [ theKey := aKey. theEnumerator := aText enumerator. ] next => theEnumerator. reset => theEnumerator. get [ var aChar := theEnumerator get. var anIndex := Letters indexOf:aChar at:0. if (-1 < anIndex) [ ^ Letters[(theKey+anIndex) mod:26] ]; [ anIndex := BigLetters indexOf:aChar at:0. if (-1 < anIndex) [ ^ BigLetters[(theKey+anIndex) mod:26] ]; [ ^ aChar ]. ]. ]
}
extension encryptOp {
encrypt : aKey = Encrypting new key:aKey text:self; summarize(String new).
decrypt :aKey = Encrypting new key(26 - aKey) text:self; summarize(String new).
}
program = [
console printLine("Original text :",TestText). var anEncryptedText := TestText encrypt:Key.
console printLine("Encrypted text:",anEncryptedText).
var aDecryptedText := anEncryptedText decrypt:Key.
console printLine("Decrypted text:",aDecryptedText).
console readChar.
].</lang>
- Output:
Original text :Pack my box with five dozen liquor jugs. Encrypted text:Bmow yk naj iuft ruhq palqz xucgad vgse. Decrypted text:Pack my box with five dozen liquor jugs.
Elixir
<lang elixir>defmodule Caesar_cipher do
defp set_map(map, range, key) do org = Enum.map(range, &List.to_string [&1]) {a, b} = Enum.split(org, key) Enum.zip(org, b ++ a) |> Enum.into(map) end def encode(text, key) do map = Map.new |> set_map(?a..?z, key) |> set_map(?A..?Z, key) String.graphemes(text) |> Enum.map_join(fn c -> Map.get(map, c, c) end) end
end
text = "The five boxing wizards jump quickly" key = 3 IO.puts "Original: #{text}" IO.puts "Encrypted: #{enc = Caesar_cipher.encode(text, key)}" IO.puts "Decrypted: #{Caesar_cipher.encode(enc, -key)}"</lang>
- Output:
Original: The five boxing wizards jump quickly Encrypted: Wkh ilyh eralqj zlcdugv mxps txlfnob Decrypted: The five boxing wizards jump quickly
Erlang
<lang Erlang> %% Ceasar cypher in Erlang for the rosetta code wiki. %% Implemented by J.W. Luiten
-module(ceasar). -export([main/2]).
%% rot: rotate Char by Key places rot(Char,Key) when (Char >= $A) and (Char =< $Z) or
(Char >= $a) and (Char =< $z) -> Offset = $A + Char band 32, N = Char - Offset, Offset + (N + Key) rem 26;
rot(Char, _Key) ->
Char.
%% key: normalize key. key(Key) when Key < 0 ->
26 + Key rem 26;
key(Key) when Key > 25 ->
Key rem 26;
key(Key) ->
Key.
main(PlainText, Key) ->
Encode = key(Key), Decode = key(-Key), io:format("Plaintext ----> ~s~n", [PlainText]), CypherText = lists:map(fun(Char) -> rot(Char, Encode) end, PlainText), io:format("Cyphertext ---> ~s~n", [CypherText]), PlainText = lists:map(fun(Char) -> rot(Char, Decode) end, CypherText).
</lang> Command: <lang Erlang>ceasar:main("The five boxing wizards jump quickly", 3).</lang>
- Output:
Plaintext ----> The five boxing wizards jump quickly Cyphertext ---> Wkh ilyh eralqj zlcdugv mxps txlfnob "The five boxing wizards jump quickly"
ERRE
<lang ERRE> PROGRAM CAESAR
!$INCLUDE="PC.LIB"
PROCEDURE CAESAR(TEXT$,KY%->CY$)
LOCAL I%,C% FOR I%=1 TO LEN(TEXT$) DO C%=ASC(MID$(TEXT$,I%)) IF (C% AND $1F)>=1 AND (C% AND $1F)<=26 THEN C%=(C% AND $E0) OR (((C% AND $1F)+KY%-1) MOD 26+1) CHANGE(TEXT$,I%,CHR$(C%)->TEXT$) END IF END FOR CY$=TEXT$
END PROCEDURE
BEGIN
RANDOMIZE(TIMER) PLAINTEXT$="Pack my box with five dozen liquor jugs" PRINT(PLAINTEXT$)
KY%=1+INT(25*RND(1)) ! generates random between 1 and 25 CAESAR(PLAINTEXT$,KY%->CYPHERTEXT$) PRINT(CYPHERTEXT$)
CAESAR(CYPHERTEXT$,26-KY%->DECYPHERED$) PRINT(DECYPHERED$)
END PROGRAM </lang>
- Output:
Pack my box with five dozen liquor jugs Qbdl nz cpy xjui gjwf epafo mjrvps kvht Pack my box with five dozen liquor jugs
Euphoria
<lang Euphoria> --caesar cipher for Rosetta Code wiki --User:Lnettnay
--usage eui caesar ->default text, key and encode flag --usage eui caesar 'Text with spaces and punctuation!' 5 D --If text has imbedded spaces must use apostophes instead of quotes so all punctuation works --key = integer from 1 to 25, defaults to 13 --flag = E (Encode) or D (Decode), defaults to E --no error checking is done on key or flag
include std/get.e include std/types.e
sequence cmd = command_line()
sequence val
-- default text for encryption
sequence text = "The Quick Brown Fox Jumps Over The Lazy Dog."
atom key = 13 -- default to Rot-13
sequence flag = "E" -- default to Encrypt
atom offset
atom num_letters = 26 -- number of characters in alphabet
--get text if length(cmd) >= 3 then text = cmd[3] end if
--get key value if length(cmd) >= 4 then val = value(cmd[4]) key = val[2] end if
--get Encrypt/Decrypt flag if length(cmd) = 5 then flag = cmd[5] if compare(flag, "D") = 0 then key = 26 - key end if end if
for i = 1 to length(text) do if t_alpha(text[i]) then if t_lower(text[i]) then offset = 'a' else offset = 'A' end if text[i] = remainder(text[i] - offset + key, num_letters) + offset end if end for
printf(1,"%s\n",{text})
</lang>
- Output:
"The Quick Brown Fox Jumps Over The Lazy Dog." encrypts to: "Gur Dhvpx Oebja Sbk Whzcf Bire Gur Ynml Qbt." decrypts to: "The Quick Brown Fox Jumps Over The Lazy Dog."
F#
<lang fsharp>module caesar =
open System
let private cipher n s = let shift c = if Char.IsLetter c then let a = (if Char.IsLower c then 'a' else 'A') |> int (int c - a + n) % 26 + a |> char else c String.map shift s
let encrypt n = cipher n let decrypt n = cipher (26 - n)</lang>
> caesar.encrypt 2 "HI";; val it : string = "JK" > caesar.encrypt 20 "HI";; val it : string = "BC" > let c = caesar.encrypt 13 "The quick brown fox jumps over the lazy dog.";; val c : string = "Gur dhvpx oebja sbk whzcf bire gur ynml qbt." > caesar.decrypt 13 c;; val it : string = "The quick brown fox jumps over the lazy dog."
Fantom
Shifts upper/lower case letters, leaves other characters as they are.
<lang fantom> class Main {
static Int shift (Int char, Int key) { newChar := char + key if (char >= 'a' && char <= 'z') { if (newChar - 'a' < 0) { newChar += 26 } if (newChar - 'a' >= 26) { newChar -= 26 } } else if (char >= 'A' && char <= 'Z') { if (newChar - 'A' < 0) { newChar += 26 } if (newChar - 'A' >= 26) { newChar -= 26 } } else // not alphabetic, so keep as is { newChar = char } return newChar }
static Str shiftStr (Str msg, Int key) { res := StrBuf() msg.each { res.addChar (shift(it, key)) } return res.toStr }
static Str encode (Str msg, Int key) { return shiftStr (msg, key) }
static Str decode (Str msg, Int key) { return shiftStr (msg, -key) }
static Void main (Str[] args) { if (args.size == 2) { msg := args[0] key := Int(args[1])
echo ("$msg with key $key") echo ("Encode: ${encode(msg, key)}") echo ("Decode: ${decode(encode(msg, key), key)}") } }
} </lang>
Example:
$ fan caesar.fan "Encrypt - With ! Case," 1 Encrypt - With ! Case, with key 1 Encode: Fodszqu - Xjui ! Dbtf, Decode: Encrypt - With ! Case, $ fan caesar.fan "Encrypt - With ! Case," 5 Encrypt - With ! Case, with key 5 Encode: Jshwduy - Bnym ! Hfxj, Decode: Encrypt - With ! Case, $ fan caesar.fan "Encrypt - With ! Case," 10 Encrypt - With ! Case, with key 10 Encode: Oxmbizd - Gsdr ! Mkco, Decode: Encrypt - With ! Case,
Forth
<lang forth>: ceasar ( c n -- c )
over 32 or [char] a - dup 0 26 within if over + 25 > if 26 - then + else 2drop then ;
- ceasar-string ( n str len -- )
over + swap do i c@ over ceasar i c! loop drop ;
- ceasar-inverse ( n -- 'n ) 26 swap - 26 mod ;
2variable test s" The five boxing wizards jump quickly!" test 2!
3 test 2@ ceasar-string test 2@ cr type
3 ceasar-inverse test 2@ ceasar-string test 2@ cr type</lang>
Fortran
<lang fortran>program Caesar_Cipher
implicit none
integer, parameter :: key = 3 character(43) :: message = "The five boxing wizards jump quickly"
write(*, "(2a)") "Original message = ", message call encrypt(message) write(*, "(2a)") "Encrypted message = ", message call decrypt(message) write(*, "(2a)") "Decrypted message = ", message
contains
subroutine encrypt(text)
character(*), intent(inout) :: text integer :: i do i = 1, len(text) select case(text(i:i)) case ('A':'Z') text(i:i) = achar(modulo(iachar(text(i:i)) - 65 + key, 26) + 65) case ('a':'z') text(i:i) = achar(modulo(iachar(text(i:i)) - 97 + key, 26) + 97) end select end do
end subroutine
subroutine decrypt(text)
character(*), intent(inout) :: text integer :: i do i = 1, len(text) select case(text(i:i)) case ('A':'Z') text(i:i) = achar(modulo(iachar(text(i:i)) - 65 - key, 26) + 65) case ('a':'z') text(i:i) = achar(modulo(iachar(text(i:i)) - 97 - key, 26) + 97) end select end do
end subroutine
end program Caesar_Cipher</lang>
- Output:
Original message = The five boxing wizards jump quickly Encrypted message = Wkh ilyh eralgj zlcdugv mxps txlfnob Decrypted message = The five boxing wizards jump quickly
FreeBASIC
<lang freebasic>' FB 1.05.0 Win64
Sub Encrypt(s As String, key As Integer)
Dim c As Integer For i As Integer = 0 To Len(s) Select Case As Const s[i] Case 65 To 90 c = s[i] + key If c > 90 Then c -= 26 s[i] = c Case 97 To 122 c = s[i] + key If c > 122 Then c -= 26 s[i] = c End Select Next
End Sub
Sub Decrypt(s As String, key As Integer)
Dim c As Integer For i As Integer = 0 To Len(s) Select Case As Const s[i] Case 65 To 90 c = s[i] - key If c < 65 Then c += 26 s[i] = c Case 97 To 122 c = s[i] - key If c < 97 Then c += 26 s[i] = c End Select Next
End Sub
Dim As String s = "Bright vixens jump; dozy fowl quack." Print "Plain text : "; s Encrypt s, 8 Print "Encrypted : "; s Decrypt s, 8 Print "Decrypted : "; s Sleep</lang>
- Output:
Plain text : Bright vixens jump; dozy fowl quack. Encrypted : Jzqopb dqfmva rcux; lwhg nwet yciks. Decrypted : Bright vixens jump; dozy fowl quack.
Gambas
Click this link to run this code <lang gambas>Public Sub Main() Dim byKey As Byte = 3 'The key (Enter 26 to get the same output as input) Dim byCount As Byte 'Counter Dim sCeasar As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ" 'Used to calculate the cipher Dim sString As String = "The five boxing wizards jump quickly" 'Phrase to encrypt Dim sCoded, sTemp As String 'Various strings
For byCount = 1 To Len(sString) 'Count through each letter in the phrase
If Mid(sString, byCount, 1) = " " Then 'If it's a space.. sCoded &= " " 'Keep it a space Continue 'Jump to the next iteration of the loop Endif sTemp = Mid(sCeasar, InStr(sCeasar, Mid(UCase(sString), byCount, 1)) + byKey, 1) 'Get the new 'coded' letter If Asc(Mid(sString, byCount, 1)) > 96 Then sTemp = Chr(Asc(sTemp) + 32) 'If the original was lower case then make the new 'coded' letter lower case sCoded &= sTemp 'Add the result to the code string
Next
Print sString & gb.NewLine & sCoded 'Print the result
End</lang> Output:
The five boxing wizards jump quickly Wkh ilyh eralqj zlcdugv mxps txlfnob
GAP
<lang gap>CaesarCipher := function(s, n) local r, c, i, lower, upper; lower := "abcdefghijklmnopqrstuvwxyz"; upper := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; r := ""; for c in s do i := Position(lower, c); if i <> fail then Add(r, lower[RemInt(i + n - 1, 26) + 1]); else i := Position(upper, c); if i <> fail then Add(r, upper[RemInt(i + n - 1, 26) + 1]); else Add(r, c); fi; fi; od; return r; end;
CaesarCipher("IBM", 25);
- "HAL"
CaesarCipher("Vgg cphvi wzdibn vmz wjmi amzz viy zlpvg di ydbidot viy mdbcon.", 5);
- "All human beings are born free and equal in dignity and rights."</lang>
GFA Basic
<lang basic> ' ' Caesar cypher ' OPENW 1 ! Creates a window for handling input/output CLEARW 1 INPUT "string to encrypt ";text$ INPUT "encryption key ";key% encrypted$=@encrypt$(UPPER$(text$),key%) PRINT "Encrypted: ";encrypted$ PRINT "Decrypted: ";@decrypt$(encrypted$,key%) ' PRINT "(Press any key to end program.)" ~INP(2) CLOSEW 1 ' FUNCTION encrypt$(text$,key%)
LOCAL result$,i%,c% result$="" FOR i%=1 TO LEN(text$) c%=ASC(MID$(text$,i%)) IF c%<ASC("A") OR c%>ASC("Z") ! don't encrypt non A-Z result$=result$+CHR$(c%) ELSE c%=c%+key% IF c%>ASC("Z") c%=c%-26 ENDIF result$=result$+CHR$(c%) ENDIF NEXT i% RETURN result$
ENDFUNC ' FUNCTION decrypt$(text$,key%)
RETURN @encrypt$(text$,26-key%)
ENDFUNC </lang>
Go
Obvious solution with explicit testing for character ranges: <lang go>package main
import (
"fmt" "strings"
)
type ckey struct {
enc, dec func(rune) rune
}
func newCaesar(k int) (*ckey, bool) {
if k < 1 || k > 25 { return nil, false } rk := rune(k) return &ckey{ enc: func(c rune) rune { if c >= 'a' && c <= 'z'-rk || c >= 'A' && c <= 'Z'-rk { return c + rk } else if c > 'z'-rk && c <= 'z' || c > 'Z'-rk && c <= 'Z' { return c + rk - 26 } return c }, dec: func(c rune) rune { if c >= 'a'+rk && c <= 'z' || c >= 'A'+rk && c <= 'Z' { return c - rk } else if c >= 'a' && c < 'a'+rk || c >= 'A' && c < 'A'+rk { return c - rk + 26 } return c }, }, true
}
func (ck ckey) encipher(pt string) string {
return strings.Map(ck.enc, pt)
}
func (ck ckey) decipher(ct string) string {
return strings.Map(ck.dec, ct)
}
func main() {
pt := "The five boxing wizards jump quickly" fmt.Println("Plaintext:", pt) for _, key := range []int{0, 1, 7, 25, 26} { ck, ok := newCaesar(key) if !ok { fmt.Println("Key", key, "invalid") continue } ct := ck.encipher(pt) fmt.Println("Key", key) fmt.Println(" Enciphered:", ct) fmt.Println(" Deciphered:", ck.decipher(ct)) }
}</lang> Data driven version using functions designed for case conversion. (And for method using % operator, see Vigenère_cipher#Go.) <lang go>package main
import (
"fmt" "strings" "unicode"
)
type ckey struct {
enc, dec unicode.SpecialCase
}
func newCaesar(k int) (*ckey, bool) {
if k < 1 || k > 25 { return nil, false } i := uint32(k) r := rune(k) return &ckey{ unicode.SpecialCase{ {'A', 'Z' - i, [3]rune{r}}, {'Z' - i + 1, 'Z', [3]rune{r - 26}}, {'a', 'z' - i, [3]rune{r}}, {'z' - i + 1, 'z', [3]rune{r - 26}}, }, unicode.SpecialCase{ {'A', 'A' + i - 1, [3]rune{26 - r}}, {'A' + i, 'Z', [3]rune{-r}}, {'a', 'a' + i - 1, [3]rune{26 - r}}, {'a' + i, 'z', [3]rune{-r}}, }, }, true
}
func (ck ckey) encipher(pt string) string {
return strings.ToUpperSpecial(ck.enc, pt)
}
func (ck ckey) decipher(ct string) string {
return strings.ToUpperSpecial(ck.dec, ct)
}
func main() {
pt := "The five boxing wizards jump quickly" fmt.Println("Plaintext:", pt) for _, key := range []int{0, 1, 7, 25, 26} { ck, ok := newCaesar(key) if !ok { fmt.Println("Key", key, "invalid") continue } ct := ck.encipher(pt) fmt.Println("Key", key) fmt.Println(" Enciphered:", ct) fmt.Println(" Deciphered:", ck.decipher(ct)) }
}</lang>
- Output:
(either version)
Plaintext: The five boxing wizards jump quickly Key 0 invalid Key 1 Enciphered: Uif gjwf cpyjoh xjabset kvnq rvjdlmz Deciphered: The five boxing wizards jump quickly Key 7 Enciphered: Aol mpcl ivepun dpghykz qbtw xbpjrsf Deciphered: The five boxing wizards jump quickly Key 25 Enciphered: Sgd ehud anwhmf vhyzqcr itlo pthbjkx Deciphered: The five boxing wizards jump quickly Key 26 invalid
Groovy
Java style: <lang groovy>def caesarEncode(cipherKey, text) {
def builder = new StringBuilder() text.each { character -> int ch = character[0] as char switch(ch) { case 'a'..'z': ch = ((ch - 97 + cipherKey) % 26 + 97); break case 'A'..'Z': ch = ((ch - 65 + cipherKey) % 26 + 65); break } builder << (ch as char) } builder as String
} def caesarDecode(cipherKey, text) { caesarEncode(26 - cipherKey, text) }</lang>
Functional style: <lang groovy>def caesarEncode(cipherKey, text) {
text.chars.collect { c -> int off = c.isUpperCase() ? 'A' : 'a' c.isLetter() ? (((c as int) - off + cipherKey) % 26 + off) as char : c }.join()
} def caesarDecode(cipherKey, text) { caesarEncode(26 - cipherKey, text) }</lang>
Ninja style: <lang groovy>def caesarEncode(k, text) {
(text as int[]).collect { it==' ' ? ' ' : (((it & 0x1f) + k - 1) % 26 + 1 | it & 0xe0) as char }.join()
} def caesarDecode(k, text) { caesarEncode(26 - k, text) }</lang>
Using built in 'tr' function and a replacement alphabet: <lang groovy>def caesarEncode(k, text) {
text.tr('a-zA-Z', ((('a'..'z')*2)[k..(k+25)] + (('A'..'Z')*2)[k..(k+25)]).join())
} def caesarDecode(cipherKey, text) { caesarEncode(26 - cipherKey, text) }</lang> and the same with closures for somewhat better readability: <lang groovy>def caesarEncode(k, text) {
def c = { (it*2)[k..(k+25)].join() } text.tr('a-zA-Z', c('a'..'z') + c('A'..'Z'))
} def caesarDecode(cipherKey, text) { caesarEncode(26 - cipherKey, text) }</lang> Test code: <lang groovy> def plainText = "The Quick Brown Fox jumped over the lazy dog" def cipherKey = 12 def cipherText = caesarEncode(cipherKey, plainText) def decodedText = caesarDecode(cipherKey, cipherText)
println "plainText: $plainText" println "cypherText($cipherKey): $cipherText" println "decodedText($cipherKey): $decodedText"
assert plainText == decodedText </lang>
- Output:
plainText: The Quick Brown Fox jumped over the lazy dog cypherText(12): Ftq Cguow Ndaiz Raj vgybqp ahqd ftq xmlk pas decodedText(12): The Quick Brown Fox jumped over the lazy dog
Haskell
<lang haskell>module Caesar (caesar, uncaesar) where
import Data.Char
caesar, uncaesar :: (Integral a) => a -> String -> String caesar k = map f
where f c = case generalCategory c of LowercaseLetter -> addChar 'a' k c UppercaseLetter -> addChar 'A' k c _ -> c
uncaesar k = caesar (-k)
addChar :: (Integral a) => Char -> a -> Char -> Char addChar b o c = chr $ fromIntegral (b' + (c' - b' + o) `mod` 26)
where b' = fromIntegral $ ord b c' = fromIntegral $ ord c
</lang>
And trying it out in GHCi:
*Main> caesar 1 "hal" "ibm" *Main> unCaesar 1 "ibm" "hal"
Similarly, but allowing for negative cipher keys, and using isAlpha, isUpper, negate:
<lang haskell>import Data.Char (ord, chr, isUpper, isAlpha)
caesar, uncaesar :: Int -> String -> String caesar = (<$>) . tr
uncaesar = caesar . negate
tr :: Int -> Char -> Char tr offset c
| isAlpha c = chr $ intAlpha + mod ((ord c - intAlpha) + offset) 26 | otherwise = c where intAlpha = ord (if isUpper c then 'A' else 'a')
main :: IO () main = mapM_ print [encoded, decoded]
where encoded = caesar (-114) "Curio, Cesare venne, e vide e vinse ? " decoded = uncaesar (-114) encoded</lang>
- Output:
"Skhye, Suiqhu luddu, u lytu u lydiu ? " "Curio, Cesare venne, e vide e vinse ? "
Or with proper error handling: <lang haskell>{-# LANGUAGE LambdaCase #-} module Main where
import Control.Error (tryRead, tryAt) import Control.Monad.Trans (liftIO) import Control.Monad.Trans.Except (ExceptT, runExceptT)
import Data.Char import System.Exit (die) import System.Environment (getArgs)
main :: IO () main = runExceptT parseKey >>= \case
Left err -> die err Right k -> interact $ caesar k
parseKey :: (Read a, Integral a) => ExceptT String IO a parseKey = liftIO getArgs >>=
flip (tryAt "Not enough arguments") 0 >>= tryRead "Key is not a valid integer"
caesar :: (Integral a) => a -> String -> String caesar k = map f
where f c = case generalCategory c of LowercaseLetter -> addChar 'a' k c UppercaseLetter -> addChar 'A' k c _ -> c
addChar :: (Integral a) => Char -> a -> Char -> Char addChar b o c = chr $ fromIntegral (b' + (c' - b' + o) `mod` 26)
where b' = fromIntegral $ ord b c' = fromIntegral $ ord c</lang>
Icon and Unicon
Strictly speaking a Ceasar Cipher is a shift of 3 (the default in this case). <lang Icon>procedure main() ctext := caesar(ptext := map("The quick brown fox jumped over the lazy dog")) dtext := caesar(ctext,,"decrypt") write("Plain text = ",image(ptext)) write("Encphered text = ",image(ctext)) write("Decphered text = ",image(dtext)) end
procedure caesar(text,k,mode) #: mono-alphabetic shift cipher /k := 3 k := (((k % *&lcase) + *&lcase) % *&lcase) + 1 case mode of {
&null|"e"|"encrypt": return map(text,&lcase,(&lcase||&lcase)[k+:*&lcase]) "d"|"decrypt" : return map(text,(&lcase||&lcase)[k+:*&lcase],&lcase) }
end</lang>
- Output:
Plain text = "the quick brown fox jumped over the lazy dog" Encphered text = "wkh txlfn eurzq ira mxpshg ryhu wkh odcb grj" Decphered text = "the quick brown fox jumped over the lazy dog"
J
If we assume that the task also requires us to leave non-alphabetic characters alone: <lang j>cndx=: [: , 65 97 +/ 26 | (i.26)&+ caesar=: (cndx 0)}&a.@u:@cndx@[ {~ a.i.]</lang> Example use:<lang j> 2 caesar 'This simple "monoalphabetic substitution cipher" provides almost no security, ...' Vjku ukorng "oqpqcnrjcdgvke uwduvkvwvkqp ekrjgt" rtqxkfgu cnoquv pq ugewtkva, ...</lang> If we instead assume the task only requires we treat upper case characters: <lang j>CAESAR=:1 :'(26|m&+)&.((26{.64}.a.)&i.)'</lang> Example use:<lang j> 20 CAESAR 'HI' BC</lang>
Java
<lang java5>public class Cipher {
public static void main(String[] args) {
String str = "The quick brown fox Jumped over the lazy Dog";
System.out.println( Cipher.encode( str, 12 )); System.out.println( Cipher.decode( Cipher.encode( str, 12), 12 )); }
public static String decode(String enc, int offset) { return encode(enc, 26-offset); }
public static String encode(String enc, int offset) { offset = offset % 26 + 26; StringBuilder encoded = new StringBuilder(); for (char i : enc.toCharArray()) { if (Character.isLetter(i)) { if (Character.isUpperCase(i)) { encoded.append((char) ('A' + (i - 'A' + offset) % 26 )); } else { encoded.append((char) ('a' + (i - 'a' + offset) % 26 )); } } else { encoded.append(i); } } return encoded.toString(); }
}</lang>
- Output:
Ftq cguow ndaiz raj Vgybqp ahqd ftq xmlk Pas The quick brown fox Jumped over the lazy Dog
JavaScript
ES5
<lang javascript>function caesar (text, shift) {
return text.toUpperCase().replace(/[^A-Z]/g,).replace(/[A-Z]/g, function(a) { return String.fromCharCode(65+(a.charCodeAt(0)-65+shift)%26); });
}
// Tests var text = 'veni, vidi, vici'; for (var i = 0; i<26; i++) {
console.log(i+': '+caesar(text,i));
}</lang>
- Output:
0: VENIVIDIVICI 1: WFOJWJEJWJDJ 2: XGPKXKFKXKEK 3: YHQLYLGLYLFL ...
ES6
<lang javascript>var caesar = (text, shift) => text
.toUpperCase() .replace(/[^A-Z]/g, ) .replace(/[A-Z]/g, a => String.fromCharCode(65 + (a.charCodeAt(0) - 65 + shift) % 26));</lang>
Or, allowing encoding and decoding of both lower and upper case:
<lang JavaScript>((key, strPlain) => {
// Int -> String -> String let caesar = (k, s) => s.split() .map(c => tr( inRange(['a', 'z'], c) ? 'a' : inRange(['A', 'Z'], c) ? 'A' : 0, k, c )) .join();
// Int -> String -> String let unCaesar = (k, s) => caesar(26 - (k % 26), s);
// Char -> Int -> Char -> Char let tr = (base, offset, char) => base ? ( String.fromCharCode( ord(base) + ( ord(char) - ord(base) + offset ) % 26 ) ) : char;
// [a, a] -> a -> b let inRange = ([min, max], v) => !(v < min || v > max);
// Char -> Int let ord = c => c.charCodeAt(0);
// range :: Int -> Int -> [Int] let range = (m, n) => Array.from({ length: Math.floor(n - m) + 1 }, (_, i) => m + i);
// TEST let strCipher = caesar(key, strPlain), strDecode = unCaesar(key, strCipher);
return [strCipher, ' -> ', strDecode];
})(114, 'Curio, Cesare venne, e vide e vinse ? ');</lang>
- Output:
Mebsy, Mockbo foxxo, o fsno o fsxco ? , -> , Curio, Cesare venne, e vide e vinse ?
Julia
<lang julia>function rot(ch::Char, key::Integer)
if key < 1 || key > 25 end if isalpha(ch) shft = ifelse(islower(ch), 'a', 'A') ch = (ch - shft + key) % 26 + shft end return ch
end rot(str::AbstractString, key::Integer) = map(x -> rot(x, key), str)
msg = "The five boxing wizards jump quickly" key = 3 invkey = 26 - 3
println("# original: $msg\n encrypted: $(rot(msg, key))\n decrypted: $(rot(rot(msg, key), invkey))")</lang>
- Output:
# original: The five boxing wizards jump quickly encrypted: Wkh ilyh eralqj zlcdugv mxps txlfnob decrypted: The five boxing wizards jump quickly
K
Assumes lowercase letters, and no punctuation.
<lang k>
s:"there is a tide in the affairs of men" caesar:{ :[" "=x; x; {x!_ci 97+!26}[y]@_ic[x]-97]}' caesar[s;1]
"uifsf jt b ujef jo uif bggbjst pg nfo" </lang>
Kotlin
<lang scala>// version 1.0.5-2
object Caesar {
fun encrypt(s: String, key: Int): String { val offset = key % 26 if (offset == 0) return s var d: Char val chars = CharArray(s.length) for ((index, c) in s.withIndex()) { if (c in 'A'..'Z') { d = c + offset if (d > 'Z') d -= 26 } else if (c in 'a'..'z') { d = c + offset if (d > 'z') d -= 26 } else d = c chars[index] = d } return chars.joinToString("") } fun decrypt(s: String, key: Int): String { return encrypt(s, 26 - key) }
}
fun main(args: Array<String>) {
val encoded = Caesar.encrypt("Bright vixens jump; dozy fowl quack.", 8) println(encoded) val decoded = Caesar.decrypt(encoded, 8) println(decoded)
}</lang>
- Output:
Jzqopb dqfmva rcux; lwhg nwet yciks. Bright vixens jump; dozy fowl quack.
LabVIEW
For readability, input is in all caps.
This image is a VI Snippet, an executable image of LabVIEW code. The LabVIEW version is shown on the top-right hand corner. You can download it, then drag-and-drop it onto the LabVIEW block diagram from a file browser, and it will appear as runnable, editable code.
Liberty BASIC
<lang lb>key = 7
Print "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
'Encrypt the text Print CaesarCypher$("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", key)
'Decrypt the text by changing the key to (26 - key) Print CaesarCypher$(CaesarCypher$("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", key), (26 - key))
Function CaesarCypher$(string$, key)
If (key < 0) Or (key > 25) Then _ CaesarCypher$ = "Key is Ouside of Bounds" : Exit Function For i = 1 To Len(string$) rotate = Asc(Mid$(string$, i, 1)) rotate = (rotate + key) If Asc(Mid$(string$, i, 1)) > Asc("Z") Then If rotate > Asc("z") Then rotate = (Asc("a") + (rotate - Asc("z")) - 1) Else If rotate > Asc("Z") Then rotate = (Asc("A") + (rotate - Asc("Z")) - 1) End If CaesarCypher$ = (CaesarCypher$ + Chr$(rotate)) Next i
End Function</lang>
LiveCode
<lang LiveCode>function caesarCipher rot phrase
local rotPhrase, lowerLetters, upperLetters put "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" into lowerLetters put "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ" into upperLetters repeat for each char letter in phrase get charTonum(letter) if it >= 65 and it <= 90 then put char ((it + rot) - 64) of upperLetters after rotPhrase else if it >= 97 and it <= 122 then put char ((it + rot) - 96) of lowerLetters after rotPhrase else put letter after rotPhrase end if end repeat return rotPhrase
end caesarCipher</lang>
Logo
<lang logo>; some useful constants make "lower_a ascii "a make "lower_z ascii "z make "upper_a ascii "A make "upper_z ascii "Z
- encipher a single character
to encipher_char :char :key
local "code make "code ascii :char local "base make "base 0 ifelse [and (:code >= :lower_a) (:code <= :lower_z)] [make "base :lower_a] [ if [and (:code >= :upper_a) (:code <= :upper_z)] [make "base :upper_a] ] ifelse [:base > 0] [ output char (:base + (modulo ( :code - :base + :key ) 26 )) ] [ output :char ]
end
- encipher a whole string
to caesar_cipher :string :key
output map [encipher_char ? :key] :string
end
- Demo
make "plaintext "|The five boxing wizards jump quickly| make "key 3 make "ciphertext caesar_cipher :plaintext :key make "recovered caesar_cipher :ciphertext -:key
print sentence "| Original:| :plaintext print sentence "|Encrypted:| :ciphertext print sentence "|Recovered:| :recovered bye</lang>
- Output:
Original: The five boxing wizards jump quickly Encrypted: Wkh ilyh eralqj zlcdugv mxps txlfnob Recovered: The five boxing wizards jump quickly
Lua
<lang Lua>local function encrypt(text, key) return text:gsub("%a", function(t) local base = (t:lower() == t and string.byte('a') or string.byte('A'))
local r = t:byte() - base r = r + key r = r%26 -- works correctly even if r is negative r = r + base return string.char(r) end) end
local function decrypt(text, key) return encrypt(text, -key) end
caesar = { encrypt = encrypt, decrypt = decrypt, }
-- test do local text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz" local encrypted = caesar.encrypt(text, 7) local decrypted = caesar.decrypt(encrypted, 7) print("Original text: ", text) print("Encrypted text: ", encrypted) print("Decrypted text: ", decrypted) end </lang>
Fast version
<lang Lua>local memo = {}
local function make_table(k)
local t = {} local a, A = ('a'):byte(), ('A'):byte()
for i = 0,25 do local c = a + i local C = A + i local rc = a + (i+k) % 26 local RC = A + (i+k) % 26 t[c], t[C] = rc, RC end
return t
end
local function caesar(str, k, decode)
k = (decode and -k or k) % 26
local t = memo[k] if not t then t = make_table(k) memo[k] = t end
local res_t = { str:byte(1,-1) } for i,c in ipairs(res_t) do res_t[i] = t[c] or c end return string.char(unpack(res_t))
end</lang>
Maple
<lang Maple> > StringTools:-Encode( "The five boxing wizards jump quickly", encoding = alpharot[3] );
"Wkh ilyh eralqj zlcdugv mxps txlfnob"
> StringTools:-Encode( %, encoding = alpharot[ 23 ] );
"The five boxing wizards jump quickly"
</lang> (The symbol % refers the the last (non-NULL) value computed.)
Mathematica / Wolfram Language
<lang Mathematica>cypher[mesg_String,n_Integer]:=StringReplace[mesg,Flatten[Thread[Rule[#,RotateLeft[#,n]]]&/@CharacterRange@@@{{"a","z"},{"A","Z"}}]]</lang>
- Output:
cypher["The five boxing wizards jump quickly",3] -> Wkh ilyh eralqj zlcdugv mxps txlfnob
MATLAB / Octave
<lang Matlab> function s = cipherCaesar(s, key)
s = char( mod(s - 'A' + key, 25 ) + 'A'); end; function s = decipherCaesar(s, key) s = char( mod(s - 'A' - key, 25 ) + 'A'); end; </lang>
Here is a test: <lang Matlab> decipherCaesar(cipherCaesar('ABC',4),4)
ans = ABC </lang>
ML
mLite
In this implementation, the offset can be positive or negative and is wrapped around if greater than 25 or less than -25. <lang ocaml>fun readfile () = readfile []
| x = let val ln = readln () in if eof ln then rev x else readfile ` ln :: x end
local val lower_a = ord #"a"; val lower_z = ord #"z"; val upper_a = ord #"A"; val upper_z = ord #"Z";
fun which (c_upper c) = (upper_a, upper_z) | _ = (lower_a, lower_z) ;
fun scale (c, az) where (c > #1 az) = scale( (#0 az + (c - #1 az - 1)), az) | (c, az) = c
in fun encipher ([], offset, t) = implode ` rev t | (x :: xs, offset, t) where (c_alphabetic x) = encipher (xs, offset, (chr ` scale (ord x + offset, which x)) :: t) | (x :: xs, offset, t) = encipher (xs, offset, x :: t) | (s, offset) = if (offset < 0) then encipher (explode s, 26 + (offset rem 26), []) else encipher (explode s, offset rem 26, []) end
fun default (false, y) = y | (x, _) = x
map println ` map (fn s = encipher (s,ston ` default (argv 0, "1"))) ` readfile (); </lang> The string for encoding is supplied as an input stream, and the offset supplied on the command line (defaults to 1). For example
echo The cat sat on the mat | mlite -f caecip.m ~5
Output:
Ocz xvo nvo ji ocz hvo
NetRexx
The cipher code in this sample is also used in the Rot-13 – NetRexx task. <lang NetRexx>/* NetRexx */
options replace format comments java crossref savelog symbols nobinary
messages = [ -
'The five boxing wizards jump quickly', - 'Attack at dawn!', - 'HI']
keys = [1, 2, 20, 25, 13]
loop m_ = 0 to messages.length - 1
in = messages[m_] loop k_ = 0 to keys.length - 1 say 'Caesar cipher, key:' keys[k_].right(3) ec = caesar_encipher(in, keys[k_]) dc = caesar_decipher(ec, keys[k_]) say in say ec say dc say end k_ say 'Rot-13:' ec = rot13(in) dc = rot13(ec) say in say ec say dc say end m_
return
method rot13(input) public static signals IllegalArgumentException
return caesar(input, 13, isFalse)
method caesar(input = Rexx, idx = int, caps = boolean) public static signals IllegalArgumentException
if idx < 1 | idx > 25 then signal IllegalArgumentException()
-- 12345678901234567890123456 itab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' shift = itab.length - idx parse itab tl +(shift) tr otab = tr || tl
if caps then input = input.upper
cipher = input.translate(itab || itab.lower, otab || otab.lower)
return cipher
method caesar_encipher(input = Rexx, idx = int, caps = boolean) public static signals IllegalArgumentException
return caesar(input, idx, caps)
method caesar_decipher(input = Rexx, idx = int, caps = boolean) public static signals IllegalArgumentException
return caesar(input, int(26) - idx, isFalse)
method caesar_encipher(input = Rexx, idx = int) public static signals IllegalArgumentException
return caesar(input, idx, isFalse)
method caesar_decipher(input = Rexx, idx = int) public static signals IllegalArgumentException
return caesar(input, int(26) - idx, isFalse)
method caesar_encipher(input = Rexx, idx = int, opt = Rexx) public static signals IllegalArgumentException
return caesar(input, idx, opt)
method caesar_decipher(input = Rexx, idx = int, opt = Rexx) public static signals IllegalArgumentException
return caesar(input, int(26) - idx, opt)
method caesar(input = Rexx, idx = int, opt = Rexx) public static signals IllegalArgumentException
if opt.upper.abbrev('U') >= 1 then caps = isTrue else caps = isFalse
return caesar(input, idx, caps)
method caesar(input = Rexx, idx = int) public static signals IllegalArgumentException
return caesar(input, idx, isFalse)
method isTrue public static returns boolean
return (1 == 1)
method isFalse public static returns boolean
return \isTrue</lang>
Caesar cipher, key: 1 The five boxing wizards jump quickly Uif gjwf cpyjoh xjabset kvnq rvjdlmz The five boxing wizards jump quickly Caesar cipher, key: 2 The five boxing wizards jump quickly Vjg hkxg dqzkpi ykbctfu lwor swkemna The five boxing wizards jump quickly Caesar cipher, key: 20 The five boxing wizards jump quickly Nby zcpy vircha qctulxm dogj kocwefs The five boxing wizards jump quickly Caesar cipher, key: 25 The five boxing wizards jump quickly Sgd ehud anwhmf vhyzqcr itlo pthbjkx The five boxing wizards jump quickly Caesar cipher, key: 13 The five boxing wizards jump quickly Gur svir obkvat jvmneqf whzc dhvpxyl The five boxing wizards jump quickly Rot-13: The five boxing wizards jump quickly Gur svir obkvat jvmneqf whzc dhvpxyl The five boxing wizards jump quickly Caesar cipher, key: 1 Attack at dawn! Buubdl bu ebxo! Attack at dawn! Caesar cipher, key: 2 Attack at dawn! Cvvcem cv fcyp! Attack at dawn! Caesar cipher, key: 20 Attack at dawn! Unnuwe un xuqh! Attack at dawn! Caesar cipher, key: 25 Attack at dawn! Zsszbj zs czvm! Attack at dawn! Caesar cipher, key: 13 Attack at dawn! Nggnpx ng qnja! Attack at dawn! Rot-13: Attack at dawn! Nggnpx ng qnja! Attack at dawn! Caesar cipher, key: 1 HI IJ HI Caesar cipher, key: 2 HI JK HI Caesar cipher, key: 20 HI BC HI Caesar cipher, key: 25 HI GH HI Caesar cipher, key: 13 HI UV HI Rot-13: HI UV HI
Nim
<lang nim>import strutils
proc caesar(s: string, k: int, decode = false): string =
var k = if decode: 26 - k else: k result = "" for i in toUpper(s): if ord(i) >= 65 and ord(i) <= 90: result.add(chr((ord(i) - 65 + k) mod 26 + 65))
let msg = "The quick brown fox jumped over the lazy dogs" echo msg let enc = caesar(msg, 11) echo enc echo caesar(enc, 11, decode = true)</lang>
Oberon-2
Works with oo2c version2 <lang oberon2> MODULE Caesar; IMPORT
Out;
CONST
encode* = 1; decode* = -1;
VAR
text,cipher: POINTER TO ARRAY OF CHAR;
PROCEDURE Cipher*(txt: ARRAY OF CHAR; key: INTEGER; op: INTEGER; VAR cipher: ARRAY OF CHAR); VAR i: LONGINT; BEGIN i := 0; WHILE i < LEN(txt) - 1 DO IF (txt[i] >= 'A') & (txt[i] <= 'Z') THEN cipher[i] := CHR(ORD('A') + ((ORD(txt[i]) - ORD('A') + (key * op))) MOD 26) ELSIF (txt[i] >= 'a') & (txt[i] <= 'z') THEN cipher[i] := CHR(ORD('a') + ((ORD(txt[i]) - ORD('a') + (key * op))) MOD 26) ELSE cipher[i] := txt[i] END; INC(i) END; cipher[i] := 0X END Cipher;
BEGIN
NEW(text,3);NEW(cipher,3); COPY("HI",text^); Out.String(text^);Out.String(" =e=> "); Cipher(text^,2,encode,cipher^); Out.String(cipher^);
COPY(cipher^,text^); Cipher(text^,2,decode,cipher^); Out.String(" =d=> ");Out.String(cipher^);Out.Ln;
COPY("ZA",text^); Out.String(text^);Out.String(" =e=> "); Cipher(text^,2,encode,cipher^); Out.String(cipher^);
COPY(cipher^,text^); Cipher(text^,2,decode,cipher^); Out.String(" =d=> ");Out.String(cipher^);Out.Ln;
NEW(text,37);NEW(cipher,37); COPY("The five boxing wizards jump quickly",text^); Out.String(text^);Out.String(" =e=> "); Cipher(text^,3,encode,cipher^); Out.String(cipher^);
COPY(cipher^,text^); Cipher(text^,3,decode,cipher^); Out.String(" =d=> ");Out.String(cipher^);Out.Ln;
END Caesar. </lang> Output:
HI =e=> JK =d=> HI ZA =e=> BC =d=> ZA The five boxing wizards jump quickly =e=> Wkh ilyh eralqj zlcdugv mxps txlfnob =d=> The five boxing wizards jump quickly
Objeck
<lang objeck> class Caesar {
function : native : Encode(enc : String, offset : Int) ~ String { offset := offset % 26 + 26; encoded := ""; enc := enc->ToLower(); each(i : enc) { c := enc->Get(i); if(c->IsChar()) { j := (c - 'a' + offset) % 26; encoded->Append(j + 'a'); } else { encoded->Append(c); }; }; return encoded; } function : Decode(enc : String, offset : Int) ~ String { return Encode(enc, offset * -1); } function : Main(args : String[]) ~ Nil { enc := Encode("The quick brown fox Jumped over the lazy Dog", 12); enc->PrintLine(); Decode(enc, 12)->PrintLine(); }
} </lang>
- Output:
ftq cguow ndaiz raj vgybqp ahqd ftq xmlk pas the quick brown fox jumped over the lazy dog
OCaml
<lang ocaml>let islower c =
c >= 'a' && c <= 'z'
let isupper c =
c >= 'A' && c <= 'Z'
let rot x str =
let upchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" and lowchars = "abcdefghijklmnopqrstuvwxyz" in let rec decal x = if x < 0 then decal (x + 26) else x in let x = (decal x) mod 26 in let decal_up = x - (int_of_char 'A') and decal_low = x - (int_of_char 'a') in let len = String.length str in let res = String.create len in for i = 0 to pred len do let c = str.[i] in if islower c then let j = ((int_of_char c) + decal_low) mod 26 in res.[i] <- lowchars.[j] else if isupper c then let j = ((int_of_char c) + decal_up) mod 26 in res.[i] <- upchars.[j] else res.[i] <- c done; (res)
(* or in OCaml 4.00+: let rot x =
let upchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" and lowchars = "abcdefghijklmnopqrstuvwxyz" in let rec decal x = if x < 0 then decal (x + 26) else x in let x = (decal x) mod 26 in let decal_up = x - (int_of_char 'A') and decal_low = x - (int_of_char 'a') in String.map (fun c -> if islower c then let j = ((int_of_char c) + decal_low) mod 26 in lowchars.[j] else if isupper c then let j = ((int_of_char c) + decal_up) mod 26 in upchars.[j] else c )
- )</lang>
<lang ocaml>let () =
let key = 3 in let orig = "The five boxing wizards jump quickly" in let enciphered = rot key orig in print_endline enciphered; let deciphered = rot (- key) enciphered in print_endline deciphered; Printf.printf "equal: %b\n" (orig = deciphered)
- </lang>
- Output:
$ ocaml caesar.ml Wkh ilyh eralqj zlcdugv mxps txlfnob The five boxing wizards jump quickly equal: true
Oforth
<lang Oforth>: ceasar(c, key)
c dup isLetter ifFalse: [ return ] isUpper ifTrue: [ 'A' ] else: [ 'a' ] c key + over - 26 mod + ;
- cipherE(s, key) s map(#[ key ceasar ]) charsAsString ;
- cipherD(s, key) cipherE(s, 26 key - ) ;</lang>
- Output:
>cipherE("Pack my box with five dozen liquor jugs.", 5) println Ufhp rd gtc bnym knaj itejs qnvztw ozlx. ok >cipherD("Ufhp rd gtc bnym knaj itejs qnvztw ozlx.", 5) println Pack my box with five dozen liquor jugs.
OOC
<lang ooc>main: func (args: String[]) {
shift := args[1] toInt() if (args length != 3) { "Usage: #{args[0]} [number] [sentence]" println() "Incorrect number of arguments." println() } else if (!shift && args[1] != "0"){ "Usage: #{args[0]} [number] [sentence]" println() "Number is not a valid number." println() } else { str := "" for (c in args[2]) { if (c alpha?()) { c = (c lower?() ? 'a' : 'A') + (26 + c toLower() - 'a' + shift) % 26 } str += c } str println() }
}</lang>
- Output:
$ ./caesar 8 "This should be a fairly original sentence." Bpqa apwctl jm i niqztg wzqoqvit amvbmvkm. $ ./caesar -9 "Yet another, fairly original sentence!" Pvk refkyvi, wrzicp fizxzerc jvekvetv!
PARI/GP
<lang parigp>enc(s,n)={
Strchr(Vecsmall(apply(k->if(k>96&&k<123,(k+n-97)%26+97, if(k>64&&k<91, (k+n-65)%26+65, k)), Vec(Vecsmall(s)))))
}; dec(s,n)=enc(s,-n);</lang>
Pascal
<lang pascal>Program CaesarCipher(output);
procedure encrypt(var message: string; key: integer);
var i: integer; begin for i := 1 to length(message) do case message[i] of 'A'..'Z': message[i] := chr(ord('A') + (ord(message[i]) - ord('A') + key) mod 26); 'a'..'z': message[i] := chr(ord('a') + (ord(message[i]) - ord('a') + key) mod 26); end; end;
procedure decrypt(var message: string; key: integer);
var i: integer; begin for i := 1 to length(message) do case message[i] of 'A'..'Z': message[i] := chr(ord('A') + (ord(message[i]) - ord('A') - key + 26) mod 26); 'a'..'z': message[i] := chr(ord('a') + (ord(message[i]) - ord('a') - key + 26) mod 26); end; end;
var
key: integer; message: string;
begin
key := 3; message := 'The five boxing wizards jump quickly'; writeln ('Original message: ', message); encrypt(message, key); writeln ('Encrypted message: ', message); decrypt(message, key); writeln ('Decrypted message: ', message);
end.</lang>
- Output:
>: ./CaesarCipher Original message: The five boxing wizards jump quickly Encrypted message: Wkh ilyh eralqj zlcdugv mxps txlfnob Decrypted message: The five boxing wizards jump quickly >:
Perl
<lang Perl>sub caesar {
my ($message, $key, $decode) = @_; $key = 26 - $key if $decode; $message =~ s/([A-Z])/chr(((ord(uc $1) - 65 + $key) % 26) + 65)/geir;
}
my $msg = 'THE FIVE BOXING WIZARDS JUMP QUICKLY'; my $enc = caesar($msg, 10); my $dec = caesar($enc, 10, 'decode');
print "msg: $msg\nenc: $enc\ndec: $dec\n"; </lang>
- Output:
msg: THE FIVE BOXING WIZARDS JUMP QUICKLY enc: DRO PSFO LYHSXQ GSJKBNC TEWZ AESMUVI dec: THE FIVE BOXING WIZARDS JUMP QUICKLY
Perl 6
<lang perl6>my @alpha = 'A' .. 'Z'; sub encrypt ( $key where 1..25, $plaintext ) {
$plaintext.trans( @alpha Z=> @alpha.rotate($key) );
} sub decrypt ( $key where 1..25, $cyphertext ) {
$cyphertext.trans( @alpha.rotate($key) Z=> @alpha );
}
my $original = 'THE FIVE BOXING WIZARDS JUMP QUICKLY'; my $en = encrypt( 13, $original ); my $de = decrypt( 13, $en );
.say for $original, $en, $de;
say 'OK' if $original eq all( map { .&decrypt(.&encrypt($original)) }, 1..25 );</lang>
- Output:
THE FIVE BOXING WIZARDS JUMP QUICKLY GUR SVIR OBKVAT JVMNEQF WHZC DHVPXYL THE FIVE BOXING WIZARDS JUMP QUICKLY OK
Phix
<lang Phix>sequence alpha_b = repeat(0,255)
alpha_b['A'..'Z'] = 'A' alpha_b['a'..'z'] = 'a'
function caesar(string s, integer key) integer ch, base
for i=1 to length(s) do ch = s[i] base = alpha_b[ch] if base then s[i] = base+remainder(ch-base+key,26) end if end for return s
end function string s = "One fine day in the middle of the night, two dead men got up to fight. \n"&
"Back to back they faced each other, drew their swords and shot each other. %^&*()[", e = caesar(s,5), r = caesar(e,26-5) ?e ?r</lang>
- Output:
Tsj knsj ifd ns ymj rniiqj tk ymj snlmy, ybt ijfi rjs lty zu yt knlmy. Gfhp yt gfhp ymjd kfhji jfhm tymjw, iwjb ymjnw xbtwix fsi xmty jfhm tymjw. %^&*()[ One fine day in the middle of the night, two dead men got up to fight. Back to back they faced each other, drew their swords and shot each other. %^&*()[
PHP
<lang php><?php function caesarEncode( $message, $key ){
$plaintext = strtolower( $message ); $ciphertext = ""; $ascii_a = ord( 'a' ); $ascii_z = ord( 'z' ); while( strlen( $plaintext ) ){ $char = ord( $plaintext ); if( $char >= $ascii_a && $char <= $ascii_z ){ $char = ( ( $key + $char - $ascii_a ) % 26 ) + $ascii_a; } $plaintext = substr( $plaintext, 1 ); $ciphertext .= chr( $char ); } return $ciphertext;
}
echo caesarEncode( "The quick brown fox Jumped over the lazy Dog", 12 ), "\n"; ?></lang>
- Output:
ftq cguow ndaiz raj vgybqp ahqd ftq xmlk pas
PicoLisp
<lang PicoLisp>(setq *Letters (apply circ (mapcar char (range 65 90))))
(de caesar (Str Key)
(pack (mapcar '((C) (cadr (nth (member C *Letters) Key))) (chop (uppc Str)) ) ) )</lang>
Test:
: (caesar "IBM" 25) -> "HAL" : (caesar @ 1) -> "IBM" : (caesar "The quick brown fox jumped over the lazy dog's back" 7) -> "AOLXBPJRIYVDUMVEQBTWLKVCLYAOLSHGFKVNZIHJR" : (caesar @ (- 26 7)) -> "THEQUICKBROWNFOXJUMPEDOVERTHELAZYDOGSBACK"
PL/I
<lang pli>caesar: procedure options (main);
declare cypher_string character (52) static initial ((2)'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); declare (text, encyphered_text) character (100) varying, offset fixed binary; get edit (text) (L); /* Read in one line of text */ get list (offset); if offset < 1 | offset > 25 then signal error; put skip list ('Plain text=', text);
encyphered_text = translate(text, substr(cypher_string, offset+1, 26), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ); put skip list ('Encyphered text=', encyphered_text);
text = translate(encyphered_text, substr(cypher_string, 27-offset, 26), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ); put skip list ('Decyphered text=', text);
end caesar;</lang>
- Output:
with offset of 5
Plain text= THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG Encyphered text= YMJVZNHPGWTBSKTCOZRUXTAJWYMJQFEDITL Decyphered text= THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG
PowerShell
<lang Powershell># Author: M. McNabb function Get-CaesarCipher { Param ( [Parameter( Mandatory=$true,ValueFromPipeline=$true)] [string] $Text,
[ValidateRange(1,25)] [int] $Key = 1,
[switch] $Decode )
begin {
$LowerAlpha = [char]'a'..[char]'z' $UpperAlpha = [char]'A'..[char]'Z'
}
process {
$Chars = $Text.ToCharArray() function encode { param ( $Char, $Alpha = [char]'a'..[char]'z' ) $Index = $Alpha.IndexOf([int]$Char) $NewIndex = ($Index + $Key) - $Alpha.Length $Alpha[$NewIndex] } function decode { param ( $Char, $Alpha = [char]'a'..[char]'z' ) $Index = $Alpha.IndexOf([int]$Char) $int = $Index - $Key if ($int -lt 0) {$NewIndex = $int + $Alpha.Length} else {$NewIndex = $int} $Alpha[$NewIndex] }
foreach ($Char in $Chars) { if ([int]$Char -in $LowerAlpha) { if ($Decode) {$Char = decode $Char} else {$Char = encode $Char} } elseif ([int]$Char -in $UpperAlpha) { if ($Decode) {$Char = decode $Char $UpperAlpha} else {$Char = encode $Char $UpperAlpha} } $Char = [char]$Char [string]$OutText += $Char }
$OutText $OutText = $null
} }</lang> Usage examples:
Encode: PS C:\> 'Pack my box with five dozen liquor jugs.' | Get-CaesarCipher -key 3 Sdfn pb era zlwk ilyh grchq oltxru mxjv. Decode: PS C:\> 'Sdfn pb era zlwk ilyh grchq oltxru mxjv.' | Get-CaesarCipher -key 3 -Decode Pack my box with five dozen liquor jugs. Encode lines of text from a file: PS C:\> Get-Content C:\Text.txt | Get-CaesarCipher -key 10 Vsxo yxo. Vsxo dgy! Vsxo drboo;
Prolog
<lang Prolog>:- use_module(library(clpfd)).
caesar :- L1 = "The five boxing wizards jump quickly", writef("Original : %s\n", [L1]),
% encryption of the sentence encoding(3, L1, L2) , writef("Encoding : %s\n", [L2]),
% deciphering on the encoded sentence encoding(3, L3, L2), writef("Decoding : %s\n", [L3]).
% encoding/decoding of a sentence encoding(Key, L1, L2) :- maplist(caesar_cipher(Key), L1, L2).
caesar_cipher(_, 32, 32) :- !.
caesar_cipher(Key, V1, V2) :- V #= Key + V1,
% we verify that we are in the limits of A-Z and a-z. ((V1 #=< 0'Z #/\ V #> 0'Z) #\/ (V1 #=< 0'z #/\ V #> 0'z) #\/ (V1 #< 0'A #/\ V2 #>= 0'A)#\/ (V1 #< 0'a #/\ V2 #>= 0'a)) #==> A,
% if we are not in these limits A is 1, otherwise 0. V2 #= V - A * 26,
% compute values of V1 and V2 label([A, V1, V2]).</lang>
- Output:
?- caesar. Original : The five boxing wizards jump quickly Encoding : Wkh ilyh eralqj zlcdugv mxps txlfnob Decoding : The five boxing wizards jump quickly true .
PureBasic
The case is maintained for alphabetic characters (uppercase/lowercase input = uppercase/lowercase output) while non-alphabetic characters, if present are included and left unchanged in the result. <lang PureBasic>Procedure.s CC_encrypt(plainText.s, key, reverse = 0)
;if reverse <> 0 then reverse the encryption (decrypt) If reverse: reverse = 26: key = 26 - key: EndIf Static alphabet$ = "ABCEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" Protected result.s, i, length = Len(plainText), letter.s, legal If key < 1 Or key > 25: ProcedureReturn: EndIf ;keep key in range For i = 1 To length letter = Mid(plainText, i, 1) legal = FindString(alphabet$, letter, 1 + reverse) If legal result + Mid(alphabet$, legal + key, 1) Else result + letter EndIf Next ProcedureReturn result
EndProcedure
Procedure.s CC_decrypt(cypherText.s, key)
ProcedureReturn CC_encrypt(cypherText, key, 1)
EndProcedure
If OpenConsole()
Define key, plainText.s, encryptedText.s, decryptedText.s key = Random(24) + 1 ;get a random key in the range 1 -> 25 plainText = "The quick brown fox jumped over the lazy dogs.": PrintN(RSet("Plain text = ", 17) + #DQUOTE$ + plainText + #DQUOTE$) encryptedText = CC_encrypt(plainText, key): PrintN(RSet("Encrypted text = ", 17) + #DQUOTE$ + encryptedText + #DQUOTE$) decryptedText = CC_decrypt(encryptedText, key): PrintN(RSet("Decrypted text = ", 17) + #DQUOTE$ + decryptedText + #DQUOTE$) Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input() CloseConsole()
EndIf</lang>
- Output:
Plain text = "The quick brown fox jumped over the lazy dogs." Encrypted text = "Znk waoiq hxuct lud pasvkj ubkx znk rgfe jumy." Decrypted text = "the quick brown fox jumped over the lazy dogs."
Alternate solution
Here is an alternate and more advanced form of the encrypt procedure. It improves on the simple version in terms of speed, in case Caesar is using the cipher on some very long documents. It is meant to replace the encrypt procedure in the previous code and produces identical results. <lang PureBasic>Procedure.s CC_encrypt(text.s, key, reverse = 0)
;if reverse <> 0 then reverse the encryption (decrypt) Protected i, *letter.Character, *resultLetter.Character, result.s = Space(Len(text)) If reverse: key = 26 - key: EndIf If key < 1 Or key > 25: ProcedureReturn: EndIf ;exit if key out of range *letter = @text: *resultLetter = @result While *letter\c Select *letter\c Case 'A' To 'Z' *resultLetter\c = ((*letter\c - 65 + key) % 26) + 65 Case 'a' To 'z' *resultLetter\c = ((*letter\c - 97 + key) % 26) + 97 Default *resultLetter\c = *letter\c EndSelect *letter + SizeOf(Character): *resultLetter + SizeOf(Character) Wend ProcedureReturn result
EndProcedure</lang>
Python
<lang Python>def caesar(s, k, decode = False): if decode: k = 26 - k return "".join([chr((ord(i) - 65 + k) % 26 + 65) for i in s.upper() if ord(i) >= 65 and ord(i) <= 90 ])
msg = "The quick brown fox jumped over the lazy dogs" print msg enc = caesar(msg, 11) print enc print caesar(enc, 11, decode = True)</lang>
- Output:
The quick brown fox jumped over the lazy dogs ESPBFTNVMCZHYQZIUFXAPOZGPCESPWLKJOZRD THEQUICKBROWNFOXJUMPEDOVERTHELAZYDOGS
Alternate solution
(for 3.x change string.maketrans
to str.maketrans
)
<lang python>import string def caesar(s, k, decode = False):
if decode: k = 26 - k return s.translate( string.maketrans( string.ascii_uppercase + string.ascii_lowercase, string.ascii_uppercase[k:] + string.ascii_uppercase[:k] + string.ascii_lowercase[k:] + string.ascii_lowercase[:k] ) )
msg = "The quick brown fox jumped over the lazy dogs" print msg enc = caesar(msg, 11) print enc print caesar(enc, 11, decode = True)</lang>
- Output:
The quick brown fox jumped over the lazy dogs Esp bftnv mczhy qzi ufxapo zgpc esp wlkj ozrd The quick brown fox jumped over the lazy dogs
Variant with memoization of translation tables
<lang python>import string def caesar(s, k = 13, decode = False, *, memo={}):
if decode: k = 26 - k k = k % 26 table = memo.get(k) if table is None: table = memo[k] = str.maketrans( string.ascii_uppercase + string.ascii_lowercase, string.ascii_uppercase[k:] + string.ascii_uppercase[:k] + string.ascii_lowercase[k:] + string.ascii_lowercase[:k]) return s.translate(table)</lang>
A compact alternative solution <lang python> from string import ascii_uppercase as abc
def caesar(s, k, decode = False):
trans = dict(zip(abc, abc[(k,26-k)[decode]:] + abc[:(k,26-k)[decode]])) return .join(trans[L] for L in s.upper() if L in abc)
msg = "The quick brown fox jumped over the lazy dogs" print(caesar(msg, 11)) print(caesar(caesar(msg, 11), 11, True)) </lang>
- Output:
ESPBFTNVMCZHYQZIUFXAPOZGPCESPWLKJOZRD THEQUICKBROWNFOXJUMPEDOVERTHELAZYDOGS
R
This is a generalization of the Rot-13 solution for R at: http://rosettacode.org/wiki/Rot-13#R . <lang R>
- based on Rot-13 solution: http://rosettacode.org/wiki/Rot-13#R
ceasar <- function(x, key) {
# if key is negative, wrap to be positive if (key < 0) { key <- 26 + key } old <- paste(letters, LETTERS, collapse="", sep="") new <- paste(substr(old, key * 2 + 1, 52), substr(old, 1, key * 2), sep="") chartr(old, new, x)
}
- simple examples from description
print(ceasar("hi",2)) print(ceasar("hi",20))
- more advanced example
key <- 3 plaintext <- "The five boxing wizards jump quickly." cyphertext <- ceasar(plaintext, key) decrypted <- ceasar(cyphertext, -key)
print(paste(" Plain Text: ", plaintext, sep="")) print(paste(" Cypher Text: ", cyphertext, sep="")) print(paste("Decrypted Text: ", decrypted, sep=""))
</lang>
- Output:
> print(ceasar("hi",2)) [1] "jk" > print(ceasar("hi",20)) [1] "bc" > print(paste("Plain Text: ", plaintext, sep="")) [1] "Plain Text: The five boxing wizards jump quickly." > print(paste("Cypher Text: ", cyphertext, sep="")) [1] "Cypher Text: Wkh ilyh eralqj zlcdugv mxps txlfnob." > print(paste("Decrypted Text: ", decrypted, sep="")) [1] "Decrypted Text: The five boxing wizards jump quickly."
Racket
<lang racket>
- lang racket
(define A (char->integer #\A)) (define Z (char->integer #\Z)) (define a (char->integer #\a)) (define z (char->integer #\z))
(define (rotate c n)
(define cnum (char->integer c)) (define (shift base) (integer->char (+ base (modulo (+ n (- cnum base)) 26)))) (cond [(<= A cnum Z) (shift A)] [(<= a cnum z) (shift a)] [else c]))
(define (caesar s n)
(list->string (for/list ([c (in-string s)]) (rotate c n))))
(define (encrypt s) (caesar s 1)) (define (decrypt s) (caesar s -1)) </lang> Example:
> (define s (encrypt "The five boxing wizards jump quickly.")) > s "Uif gjwf cpyjoh xjabset kvnq rvjdlmz." > (decrypt s) "The five boxing wizards jump quickly."
Retro
Retro provides a number of classical cyphers in the crypto' library. This implementation is from the library. <lang Retro>{{
variable offset : rotate ( cb-c ) tuck - @offset + 26 mod + ; : rotate? ( c-c ) dup 'a 'z within [ 'a rotate ] ifTrue dup 'A 'Z within [ 'A rotate ] ifTrue ;
---reveal---
: ceaser ( $n-$ ) !offset dup [ [ @ rotate? ] sip ! ] ^types'STRING each@ ;
}}
( Example ) "THEYBROKEOURCIPHEREVERYONECANREADTHIS" 3 ceaser ( returns encrypted string ) 23 ceaser ( returns decrypted string )</lang>
REXX
only Latin letters
This version conforms to the task's restrictions. <lang rexx>/*REXX program supports the Caesar cypher for the Latin alphabet only, no punctuation */ /*──────────── or blanks allowed, all lowercase Latin letters are treated as uppercase.*/ parse arg key .; arg . p /*get key & uppercased text to be used.*/ p=space(p,0) /*elide any and all spaces (blanks). */
say 'Caesar cypher key:' key /*echo the Caesar cypher key to console*/ say ' plain text:' p /* " " plain text " " */
y=Caesar(p, key); say ' cyphered:' y /* " " cyphered text " " */ z=Caesar(y,-key); say ' uncyphered:' z /* " " uncyphered text " " */ if z\==p then say "plain text doesn't match uncyphered cyphered text." exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ Caesar: procedure; arg s,k; @='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
ak=abs(k) /*obtain the absolute value of the key.*/ L=length(@) /*obtain the length of the @ string. */ if ak>length(@)-1 | k==0 then call err k 'key is invalid.' _=verify(s,@) /*any illegal characters specified ? */ if _\==0 then call err 'unsupported character:' substr(s, _, 1) if k>0 then ky=k+1 /*either cypher it, or ··· */ else ky=L+1-ak /* decypher it. */ return translate(s, substr(@||@,ky,L),@) /*return the processed text. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
err: say; say '***error***'; say; say arg(1); say; exit 13</lang>
output when using the input of:
22 The definition of a trivial program is one that has no bugs
Caesar cypher key: 22 plain text: THEDEFINITIONOFATRIVIALPROGRAMISONETHATHASNOBUGS cyphered: PDAZABEJEPEKJKBWPNEREWHLNKCNWIEOKJAPDWPDWOJKXQCO uncyphered: THEDEFINITIONOFATRIVIALPROGRAMISONETHATHASNOBUGS
most characters
This version allows upper and lowercase Latin alphabet as well as all the characters on the standard (computer) keyboard including blanks. <lang rexx>/*REXX program supports the Caesar cypher for most keyboard characters including blanks.*/ parse arg key p /*get key and the text to be cyphered. */
say 'Caesar cypher key:' key /*echo the Caesar cypher key to console*/ say ' plain text:' p /* " " plain text " " */
y=Caesar(p, key); say ' cyphered:' y /* " " cyphered text " " */ z=Caesar(y,-key); say ' uncyphered:' z /* " " uncyphered text " " */ if z\==p then say "plain text doesn't match uncyphered cyphered text." exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ Caesar: procedure; parse arg s,k; @= 'abcdefghijklmnopqrstuvwxyz'
@=translate(@)@"0123456789(){}[]<>'" /*add uppercase, digitss, group symbols*/ @=@'~!@#$%^&*_+:";?,./`-= ' /*also add other characters to the list*/ L=length(@) /*obtain the length of the @ string. */ ak=abs(k) /*obtain the absolute value of the key.*/ if ak>length(@)-1 | k==0 then call err k 'key is invalid.' _=verify(s,@) /*any illegal characters specified ? */ if _\==0 then call err 'unsupported character:' substr(s, _, 1) if k>0 then ky=k+1 /*either cypher it, or ··· */ else ky=L+1-ak /* decypher it. */ return translate(s, substr(@ || @, ky, L), @)
/*──────────────────────────────────────────────────────────────────────────────────────*/
err: say; say '***error***'; say; say arg(1); say; exit 13</lang>
output when using the input of:
31 Batman's hood is called a "cowl" (old meaning).
Caesar cypher key: 31 plain text: Batman's hood is called a "cowl" (old meaning). cyphered: g5^>5~e%d{!!8d}%d75<<98d5dU7!_<UdA!<8d>95~}~)BY uncyphered: Batman's hood is called a "cowl" (old meaning).
Ring
<lang ring>
- Project : Caesar cipher
- Date : 2017/11/11
- Author : Gal Zsolt (~ CalmoSoft ~)
- Email : <calmosoft@gmail.com>
cipher = "pack my box with five dozen liquor jugs" abc = "abcdefghijklmnopqrstuvwxyz" see "text is to be encrypted:" + nl see cipher+ nl + nl str = "" key = random(24) + 1 see "key = " + key + nl + nl see "encrypted:" + nl caesarencode(cipher, key) see str + nl + nl cipher = str see "decrypted again:" + nl caesardecode(cipher, key) see str + nl
func caesarencode(cipher, key)
str = "" for n= 1 to len(cipher) if cipher[n] != " " pos = substr(abc, cipher[n]) if pos + key < len(abc) str = str + abc[pos + key] else if (pos+key)-len(abc) != 0 str = str + abc[(pos+key)%len(abc)] else str = str +abc[key+pos] ok ok else str = str + " " ok next return str
func caesardecode(cipher, key)
str = "" for n= 1 to len(cipher) if cipher[n] != " " pos = substr(abc, cipher[n]) if (pos - key) > 0 and pos != key str = str + abc[pos - key] loop else if pos = key str = str + char(122) else str = str + abc[len(abc)-(key-pos)] ok ok else str = str + " " ok next return str
</lang> Output:
text is to be encrypted: pack my box with five dozen liquor jugs key = 9 encrypted: yjlt vh kxg frcq oren mxinw urzdxa sdpb decrypted again: pack my box with five dozen liquor jugs
Ruby
<lang ruby>class String
ALFABET = ("A".."Z").to_a
def caesar_cipher(num) self.tr(ALFABET.join, ALFABET.rotate(num).join) end
end
- demo:
encypted = "THEYBROKEOURCIPHEREVERYONECANREADTHIS".caesar_cipher(3) decrypted = encypted.caesar_cipher(-3) </lang>
Run BASIC
<lang runbasic>input "Gimme a ofset:";ofst ' set any offset you like
a$ = "Pack my box with five dozen liquor jugs" print " Original: ";a$ a$ = cipher$(a$,ofst) print "Encrypted: ";a$ print "Decrypted: ";cipher$(a$,ofst+6)
FUNCTION cipher$(a$,ofst) for i = 1 to len(a$)
aa$ = mid$(a$,i,1) code$ = " " if aa$ <> " " then ua$ = upper$(aa$) a = asc(ua$) - 64 code$ = chr$((((a mod 26) + ofst) mod 26) + 65) if ua$ <> aa$ then code$ = lower$(code$) end if cipher$ = cipher$;code$
next i END FUNCTION</lang>
- Output:
Gimme a ofset:?9 Original: Pack my box with five dozen liquor jugs Encrypted: Zkmu wi lyh gsdr psfo nyjox vsaeyb teqc Decrypted: Pack my box with five dozen liquor jugs
Rust
This example shows proper error handling. It skips non-ASCII characters. <lang rust>use std::io::{self, Write}; use std::fmt::Display; use std::{env, process};
fn main() {
let shift: u8 = env::args().nth(1) .unwrap_or_else(|| exit_err("No shift provided", 2)) .parse() .unwrap_or_else(|e| exit_err(e, 3));
let plain = get_input() .unwrap_or_else(|e| exit_err(&e, e.raw_os_error().unwrap_or(-1)));
let cipher = plain.chars() .map(|c| { let case = if c.is_uppercase() {'A'} else {'a'} as u8; if c.is_alphabetic() { (((c as u8 - case + shift) % 26) + case) as char } else { c } }).collect::<String>();
println!("Cipher text: {}", cipher.trim());
}
fn get_input() -> io::Result<String> {
print!("Plain text: "); try!(io::stdout().flush());
let mut buf = String::new(); try!(io::stdin().read_line(&mut buf)); Ok(buf)
}
fn exit_err<T: Display>(msg: T, code: i32) -> ! {
let _ = writeln!(&mut io::stderr(), "ERROR: {}", msg); process::exit(code);
}</lang>
Scala
<lang scala>object Caesar {
private val alphaU='A' to 'Z' private val alphaL='a' to 'z'
def encode(text:String, key:Int)=text.map{ case c if alphaU.contains(c) => rot(alphaU, c, key) case c if alphaL.contains(c) => rot(alphaL, c, key) case c => c } def decode(text:String, key:Int)=encode(text,-key) private def rot(a:IndexedSeq[Char], c:Char, key:Int)=a((c-a.head+key+a.size)%a.size)
}</lang> <lang scala>val text="The five boxing wizards jump quickly" println("Plaintext => " + text) val encoded=Caesar.encode(text, 3) println("Ciphertext => " + encoded) println("Decrypted => " + Caesar.decode(encoded, 3))</lang>
- Output:
Plaintext => The five boxing wizards jump quickly Ciphertext => Wkh ilyh eralqj zlcdugv mxps txlfnob Decrypted => The five boxing wizards jump quickly
Alternate version
This version first creates non shifted and shifted character sequences and then encodes and decodes by indexing between those sequences. <lang scala>class Caeser(val key: Int) {
@annotation.tailrec private def rotate(p: Int, s: IndexedSeq[Char]): IndexedSeq[Char] = if (p < 0) rotate(s.length + p, s) else s.drop(p) ++ s.take(p)
val uc = 'A' to 'Z' val lc = 'a' to 'z' val as = uc ++ lc val bs = rotate(key, uc) ++ rotate(key, lc) def encode(c: Char) = if (as.contains(c)) bs(as.indexOf(c)) else c def decode(c: Char) = if (bs.contains(c)) as(bs.indexOf(c)) else c
}</lang>
<lang scala>val text = "The five boxing wizards jump quickly" val myCaeser = new Caeser(3) val encoded = text.map(c => myCaeser.encode(c)) println("Plaintext => " + text) println("Ciphertext => " + encoded) println("Decrypted => " + encoded.map(c => myCaeser.decode(c)))</lang>
- Output:
Plaintext => The five boxing wizards jump quickly Ciphertext => Wkh ilyh eralqj zlcdugv mxps txlfnob Decrypted => The five boxing wizards jump quickly
Scheme
<lang scheme>;
- Works with R7RS-compatible Schemes (e.g. Chibi).
- Also current versions of Chicken, Gauche and Kawa.
(cond-expand
(chicken (use srfi-13)) (gauche (use srfi-13)) (kawa (import (srfi :13))) (else (import (scheme base) (scheme write)))) ; R7RS
(define msg "The quick brown fox jumps over the lazy dog.")
(define key 13)
(define (caesar char)
(define A (char->integer #\A)) (define Z (char->integer #\Z)) (define a (char->integer #\a)) (define z (char->integer #\z)) (define c (char->integer char)) (integer->char (cond ((<= A c Z) (+ A (modulo (+ key (- c A)) 26))) ((<= a c z) (+ a (modulo (+ key (- c a)) 26))) (else c)))) ; Return other characters verbatim.
(display (string-map caesar msg)) (newline) </lang>
- Output:
Gur dhvpx oebja sbk whzcf bire gur ynml qbt.
sed
This code is roughly equivalent to the rot-13 cypher sed implementation, except that the conversion table is parameterized by a number and that the conversion done manually, instead of using `y///' command. <lang sed>#!/bin/sed -rf
- Input: <number 0..25>\ntext to encode
/^[0-9]+$/ { # validate a number and translate it to analog form s/$/;9876543210dddddddddd/ s/([0-9]);.*\1.{10}(.?)/\2/ s/2/11/ s/1/dddddddddd/g /[3-9]|d{25}d+/ { s/.*/Error: Key must be <= 25/ q } # append from-table s/$/\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/ # .. and to-table s/$/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/ # rotate to-table, lower and uppercase independently, removing one `d' at a time : rotate s/^d(.*\n[^Z]+Z)(.)(.{25})(.)(.{25})/\1\3\2\5\4/ t rotate s/\n// h d }
- use \n to mark character to convert
s/^/\n/
- append conversion table to pattern space
G
- loop
# look up converted character and place it instead of old one s/\n(.)(.*\n.*\1.{51}(.))/\n\3\2/ # advance \n even if prev. command fails, thus skip non-alphabetical characters /\n\n/! s/\n([^\n])/\1\n/ t loop s/\n\n.*//</lang>
- Output:
$ ./caesar.sed 3 The five boxing wizards jump quickly Wkh ilyh eralqj zlcdugv mxps txlfnob 23 Wkh ilyh eralqj zlcdugv mxps txlfnob The five boxing wizards jump quickly 26 Error: Key must be <= 25
Seed7
<lang seed7>$ include "seed7_05.s7i";
const func string: rot (in string: stri, in integer: encodingKey) is func
result var string: encodedStri is ""; local var char: ch is ' '; var integer: index is 0; begin encodedStri := stri; for ch key index range stri do if ch >= 'a' and ch <= 'z' then ch := chr((ord(ch) - ord('a') + encodingKey) rem 26 + ord('a')); elsif ch >= 'A' and ch <= 'Z' then ch := chr((ord(ch) - ord('A') + encodingKey) rem 26 + ord('A')); end if; encodedStri @:= [index] ch; end for; end func;
const proc: main is func
local const integer: exampleKey is 3; const string: testText is "The five boxing wizards jump quickly"; begin writeln("Original: " <& testText); writeln("Encrypted: " <& rot(testText, exampleKey)); writeln("Decrypted: " <& rot(rot(testText, exampleKey), 26 - exampleKey)); end func;</lang>
- Output:
Original: The five boxing wizards jump quickly Encrypted: Wkh ilyh eralqj zlcdugv mxps txlfnob Decrypted: The five boxing wizards jump quickly
SequenceL
You only have to write an encrypt and decrypt function for characters. The semantics of Normalize Transpose allow those functions to be applied to strings. <lang sequencel>import <Utilities/Sequence.sl>; import <Utilities/Conversion.sl>;
lowerAlphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; upperAlphabet := "abcdefghijklmnopqrstuvwxyz";
caesarEncrypt(ch, key) := let correctAlphabet := lowerAlphabet when some(ch = lowerAlphabet) else upperAlphabet;
index := Sequence::firstIndexOf(correctAlphabet, ch);
newIndex := (index + key - 1) mod 26 + 1; in ch when not(some(ch = lowerAlphabet) or some(ch = upperAlphabet)) else correctAlphabet[newIndex];
caesarDecrypt(ch, key) := caesarEncrypt(ch, 26 - key);
main(args(2)) := let key := Conversion::stringToInt(args[2]); encrypted := caesarEncrypt(args[1], key); decrypted := caesarDecrypt(encrypted, key); in "Input: \t" ++ args[1] ++ "\n" ++ "Encrypted:\t" ++ encrypted ++ "\n" ++ "Decrypted:\t" ++ decrypted;</lang>
- Output:
cmd:> main.exe "Pack my box with five dozen liquor jugs." 5 "Original: Pack my box with five dozen liquor jugs. Encrypted: Ufhp rd gtc bnym knaj itejs qnvztw ozlx. Decrypted: Pack my box with five dozen liquor jugs."
Sidef
<lang ruby>func caesar(msg, key, decode=false) {
decode && (key = (26 - key)); msg.gsub(/([A-Z])/i, {|c| ((c.uc.ord - 65 + key) % 26) + 65 -> chr});
};
var msg = 'THE FIVE BOXING WIZARDS JUMP QUICKLY';
var enc = caesar(msg, 10); var dec = caesar(enc, 10, true);
say "msg: #{msg}"; say "enc: #{enc}"; say "dec: #{dec}";</lang>
- Output:
msg: THE FIVE BOXING WIZARDS JUMP QUICKLY enc: DRO PSFO LYHSXQ GSJKBNC TEWZ AESMUVI dec: THE FIVE BOXING WIZARDS JUMP QUICKLY
Sinclair ZX81 BASIC
Works with 1k of RAM. A negative key decodes. <lang basic> 10 INPUT KEY
20 INPUT T$ 30 LET C$="" 40 FOR I=1 TO LEN T$ 50 LET L$=T$(I) 60 IF L$<"A" OR L$>"Z" THEN GOTO 100 70 LET L$=CHR$ (CODE L$+KEY) 80 IF L$>"Z" THEN LET L$=CHR$ (CODE L$-26) 90 IF L$<"A" THEN LET L$=CHR$ (CODE L$+26)
100 LET C$=C$+L$ 110 NEXT I 120 PRINT C$</lang>
- Input:
12 GALLIA EST OMNIS DIVISA IN PARTES TRES
- Output:
SMXXUM QEF AYZUE PUHUEM UZ BMDFQE FDQE
- Input:
-12 SMXXUM QEF AYZUE PUHUEM UZ BMDFQE FDQE
- Output:
GALLIA EST OMNIS DIVISA IN PARTES TRES
Smalltalk
well, I'm lucky: the standard library already contains a rot:n method! <lang Smalltalk>'THE QUICK BROWN FOX' rot:3 -> 'WKH TXLFN EURZQ IRA' </lang> but if it wasn't, here is an implementation for other smalltalks: <lang smalltalk> !CharacterArray methodsFor:'encoding'! rot:n
^ self class streamContents:[:aStream | self do:[:char | aStream nextPut:(char rot:n) ]]
!Character methodsFor:'encoding'!
rot:n
(self isLetter) ifTrue:[ self isLowercase ifTrue:[ ^ 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz' at:(self-$a+1+n) ] ifFalse:[ ^ 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ' at:(self-$A+1+n) ] ]. ^ self
</lang>
SSEM
ASCII didn't exit in 1948, and the task specification explicitly says we only need to convert Roman capitals; so we adopt a simpler encoding, representing the letters of the alphabet from A=0 to Z=25.
The program will convert one character at a time. Load the character code into storage address 20, and the key into address 19. The machine will halt with the cyphered encoding in the accumulator. A negative (two's complement) key decodes.
This is in fact a general solution that will work equally well with alphabets of more or fewer than 26 characters: simply replace the constant 26 in storage address 18 with 22 for Hebrew, 24 for Greek, 28 for Arabic, 33 for Russian, etc. <lang ssem>00101000000000100000000000000000 0. -20 to c 11001000000000010000000000000000 1. Sub. 19 10101000000001100000000000000000 2. c to 21 10101000000000100000000000000000 3. -21 to c 00000000000000110000000000000000 4. Test 10001000000000000000000000000000 5. 17 to CI 10101000000001100000000000000000 6. c to 21 10101000000000100000000000000000 7. -21 to c 01001000000000010000000000000000 8. Sub. 18 10101000000001100000000000000000 9. c to 21 10101000000000100000000000000000 10. -21 to c 00000000000001110000000000000000 11. Stop 01001000000000010000000000000000 12. Sub. 18 00000000000000110000000000000000 13. Test 00000000000001110000000000000000 14. Stop 10101000000000100000000000000000 15. -21 to c 00000000000001110000000000000000 16. Stop 11010000000000000000000000000000 17. 11 01011000000000000000000000000000 18. 26</lang>
Stata
<lang stata>function caesar(s, k) { u = ascii(s) i = selectindex(u:>=65 :& u:<=90) if (length(i)>0) u[i] = mod(u[i]:+(k-65), 26):+65 i = selectindex(u:>=97 :& u:<=122) if (length(i)>0) u[i] = mod(u[i]:+(k-97), 26):+97 return(char(u)) }
caesar("layout", 20)
fusion</lang>
Swift
<lang swift>var arr:[Character]=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
func res(st:String,ar:[Character],x:Int,ro:String)->String{
var str2:[Character]=[] for i in st.characters { for j in 0...25 { if i==ar[j] { switch ro { case "right": if(j+x<=25) { str2.append(ar[j+x]) break } else { str2.append(ar[j+x-26]) break } case "left": if(j-x>=0) { str2.append(ar[j-x]) break } else { str2.append(ar[j-x+26]) break } default: print("incorrect input for rotation direction") } } } } return String(str2)
}
var mssg:String="hi" var x1:Int=5 var rot:String="right" var rotstr:String=res(st:mssg,ar:arr,x:x1,ro:rot) print(rotstr) </lang>
Tcl
<lang tcl>package require Tcl 8.6; # Or TclOO package for 8.5
oo::class create Caesar {
variable encryptMap decryptMap constructor shift {
for {set i 0} {$i < 26} {incr i} { # Play fast and loose with string/list duality for shorter code append encryptMap [format "%c %c %c %c " \ [expr {$i+65}] [expr {($i+$shift)%26+65}] \ [expr {$i+97}] [expr {($i+$shift)%26+97}]] append decryptMap [format "%c %c %c %c " \ [expr {$i+65}] [expr {($i-$shift)%26+65}] \ [expr {$i+97}] [expr {($i-$shift)%26+97}]] }
}
method encrypt text {
string map $encryptMap $text
} method decrypt text {
string map $decryptMap $text
}
}</lang> Demonstrating: <lang tcl>set caesar [Caesar new 3] set txt "The five boxing wizards jump quickly." set enc [$caesar encrypt $txt] set dec [$caesar decrypt $enc] puts "Original message = $txt" puts "Encrypted message = $enc" puts "Decrypted message = $dec"</lang>
- Output:
Original message = The five boxing wizards jump quickly. Encrypted message = Wkh ilyh eralqj zlcdugv mxps txlfnob. Decrypted message = The five boxing wizards jump quickly.
TUSCRIPT
<lang tuscript>$$ MODE TUSCRIPT text="THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG" PRINT "text orginal ",text
abc="ABCDEFGHIJKLMNOPQRSTUVWXYZ",key=3,caesarskey=key+1 secretbeg=EXTRACT (abc,#caesarskey,0) secretend=EXTRACT (abc,0,#caesarskey) secretabc=CONCAT (secretbeg,secretend)
abc=STRINGS (abc,":</:"),secretabc=STRINGS (secretabc,":</:") abc=SPLIT (abc), secretabc=SPLIT (secretabc) abc2secret=JOIN(abc," ",secretabc),secret2abc=JOIN(secretabc," ",abc)
BUILD X_TABLE abc2secret=* DATA {abc2secret}
BUILD X_TABLE secret2abc=* DATA {secret2abc}
ENCODED = EXCHANGE (text,abc2secret) PRINT "text encoded ",encoded
DECODED = EXCHANGE (encoded,secret2abc) PRINT "encoded decoded ",decoded</lang>
- Output:
text orginal THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG text encoded WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ encoded decoded THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
TXR
The strategy here, one of many possible ones, is to build, at run time,the arguments to be passed to deffilter to construct a pair of filters enc
and dec
for encoding and decoding. Filters are specified as tuples of strings.
<lang txr>@(next :args)
@(cases)
@{key /[0-9]+/}
@text
@(or)
@ (throw error "specify <key-num> <text>")
@(end)
@(do
(defvar k (int-str key 10)))
@(bind enc-dec
@(collect-each ((i (range 0 25))) (let* ((p (tostringp (+ #\a i))) (e (tostringp (+ #\a (mod (+ i k) 26)))) (P (upcase-str p)) (E (upcase-str e))) ^(((,p ,e) (,P ,E)) ((,e ,p) (,E ,P))))))
@(deffilter enc . @(mappend (fun first) enc-dec)) @(deffilter dec . @(mappend (fun second) enc-dec)) @(output) encoded: @{text :filter enc} decoded: @{text :filter dec} @(end)</lang>
- Output:
$ ./txr caesar.txr 12 'Hello, world!' encoded: Tqxxa, iadxp! decoded: Vszzc, kcfzr! $ ./txr caesar.txr 12 'Vszzc, kcfzr!' encoded: Hello, world! decoded: Jgnnq, yqtnf!
TypeScript
<lang javascript>function replace(input: string, key: number) : string { return input.replace(/([a-z])/g, ($1) => String.fromCharCode(($1.charCodeAt(0) + key + 26 - 97) % 26 + 97) ).replace(/([A-Z])/g, ($1) => String.fromCharCode(($1.charCodeAt(0) + key + 26 - 65) % 26 + 65)); }
// test var str = 'The five boxing wizards jump quickly'; var encoded = replace(str, 3); var decoded = replace(encoded, -3);
console.log('Enciphered: ' + encoded); console.log('Deciphered: ' + decoded);</lang>
UNIX Shell
I added a tr function to make this "pure" bash. In practice, you'd remove that function and use the external tr utility. <lang bash>caesar() {
local OPTIND local encrypt n=0 while getopts :edn: option; do case $option in e) encrypt=true ;; d) encrypt=false ;; n) n=$OPTARG ;; :) echo "error: missing argument for -$OPTARG" >&2 return 1 ;; ?) echo "error: unknown option -$OPTARG" >&2 return 1 ;; esac done shift $((OPTIND-1)) if -z $encrypt ; then echo "error: specify one of -e or -d" >&2 return 1 fi
local upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ local lower=abcdefghijklmnopqrstuvwxyz if $encrypt; then tr "$upper$lower" "${upper:n}${upper:0:n}${lower:n}${lower:0:n}" <<< "$1" else tr "${upper:n}${upper:0:n}${lower:n}${lower:0:n}" "$upper$lower" <<< "$1" fi
}
tr() {
local -A charmap local i trans line char for ((i=0; i<${#1}; i++)); do charmap[${1:i:1}]=${2:i:1} done while IFS= read -r line; do trans="" for ((i=0; i<${#line}; i++)); do char=${line:i:1} if [[ -n ${charmap[$char]} ]]; then trans+=${charmap[$char]} else trans+=$char fi done echo "$trans" done
}
txt="The five boxing wizards jump quickly." enc=$(caesar -e -n 5 "$txt") dec=$(caesar -d -n 5 "$enc")
echo "original: $txt" echo "encrypted: $enc" echo "decrypted: $dec"</lang>
- Output:
original: The five boxing wizards jump quickly. encrypted: Ymj knaj gtcnsl bnefwix ozru vznhpqd. decrypted: The five boxing wizards jump quickly.
Ursa
<lang ursa>decl string mode while (not (or (= mode "encode") (= mode "decode"))) out "encode/decode: " console set mode (lower (in string console)) end while
decl string message out "message: " console set message (upper (in string console))
decl int key out "key: " console set key (in int console) if (or (> key 26) (< key 0)) out endl "invalid key" endl console stop end if
if (= mode "decode") set key (int (- 26 key)) end if
for (decl int i) (< i (size message)) (inc i) if (and (> (ord message) 64) (< (ord message) 91)) out (chr (int (+ (mod (int (+ (- (ord message) 65) key)) 26) 65))) console end if end for out endl console</lang>
Ursala
The reification operator (-:
) generates efficient code for applications like this given a table of inputs and outputs, which is obtained in this case by zipping the alphabet with itself rolled the right number of times, done separately for the upper and lower case letters and then combined.
<lang Ursala>#import std
- import nat
enc "n" = * -:~&@T ^p(rep"n" ~&zyC,~&)~~K30K31X letters # encryption function dec "n" = * -:~&@T ^p(~&,rep"n" ~&zyC)~~K30K31X letters # decryption function
plaintext = 'the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY'
- show+ # exhaustive test
test = ("n". <.enc"n",dec"n"+ enc"n"> plaintext)*= nrange/1 25</lang>
- Output:
uif gjwf cpyjoh xjabset kvnq rvjdlmz UIF GJWF CPYJOH XJABSET KVNQ RVJDLMZ the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY vjg hkxg dqzkpi ykbctfu lwor swkemna VJG HKXG DQZKPI YKBCTFU LWOR SWKEMNA the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY wkh ilyh eralqj zlcdugv mxps txlfnob WKH ILYH ERALQJ ZLCDUGV MXPS TXLFNOB the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY xli jmzi fsbmrk amdevhw nyqt uymgopc XLI JMZI FSBMRK AMDEVHW NYQT UYMGOPC the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY ymj knaj gtcnsl bnefwix ozru vznhpqd YMJ KNAJ GTCNSL BNEFWIX OZRU VZNHPQD the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY znk lobk hudotm cofgxjy pasv waoiqre ZNK LOBK HUDOTM COFGXJY PASV WAOIQRE the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY aol mpcl ivepun dpghykz qbtw xbpjrsf AOL MPCL IVEPUN DPGHYKZ QBTW XBPJRSF the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY bpm nqdm jwfqvo eqhizla rcux ycqkstg BPM NQDM JWFQVO EQHIZLA RCUX YCQKSTG the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY cqn oren kxgrwp frijamb sdvy zdrltuh CQN OREN KXGRWP FRIJAMB SDVY ZDRLTUH the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY dro psfo lyhsxq gsjkbnc tewz aesmuvi DRO PSFO LYHSXQ GSJKBNC TEWZ AESMUVI the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY esp qtgp mzityr htklcod ufxa bftnvwj ESP QTGP MZITYR HTKLCOD UFXA BFTNVWJ the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY ftq ruhq najuzs iulmdpe vgyb cguowxk FTQ RUHQ NAJUZS IULMDPE VGYB CGUOWXK the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY gur svir obkvat jvmneqf whzc dhvpxyl GUR SVIR OBKVAT JVMNEQF WHZC DHVPXYL the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY hvs twjs pclwbu kwnofrg xiad eiwqyzm HVS TWJS PCLWBU KWNOFRG XIAD EIWQYZM the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY iwt uxkt qdmxcv lxopgsh yjbe fjxrzan IWT UXKT QDMXCV LXOPGSH YJBE FJXRZAN the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY jxu vylu renydw mypqhti zkcf gkysabo JXU VYLU RENYDW MYPQHTI ZKCF GKYSABO the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY kyv wzmv sfozex nzqriuj aldg hlztbcp KYV WZMV SFOZEX NZQRIUJ ALDG HLZTBCP the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY lzw xanw tgpafy oarsjvk bmeh imaucdq LZW XANW TGPAFY OARSJVK BMEH IMAUCDQ the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY max ybox uhqbgz pbstkwl cnfi jnbvder MAX YBOX UHQBGZ PBSTKWL CNFI JNBVDER the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY nby zcpy vircha qctulxm dogj kocwefs NBY ZCPY VIRCHA QCTULXM DOGJ KOCWEFS the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY ocz adqz wjsdib rduvmyn ephk lpdxfgt OCZ ADQZ WJSDIB RDUVMYN EPHK LPDXFGT the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY pda bera xktejc sevwnzo fqil mqeyghu PDA BERA XKTEJC SEVWNZO FQIL MQEYGHU the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY qeb cfsb ylufkd tfwxoap grjm nrfzhiv QEB CFSB YLUFKD TFWXOAP GRJM NRFZHIV the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY rfc dgtc zmvgle ugxypbq hskn osgaijw RFC DGTC ZMVGLE UGXYPBQ HSKN OSGAIJW the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY sgd ehud anwhmf vhyzqcr itlo pthbjkx SGD EHUD ANWHMF VHYZQCR ITLO PTHBJKX the five boxing wizards jump quickly THE FIVE BOXING WIZARDS JUMP QUICKLY
Vala
This is a port of the C# code present in this page. <lang Vala>static void println(string str) {
stdout.printf("%s\r\n", str);
}
static unichar encrypt_char(unichar ch, int code) {
if (!ch.isalpha()) return ch;
unichar offset = ch.isupper() ? 'A' : 'a'; return (unichar)((ch + code - offset) % 26 + offset);
}
static string encrypt(string input, int code) {
var builder = new StringBuilder();
unichar c; for (int i = 0; input.get_next_char(ref i, out c);) { builder.append_unichar(encrypt_char(c, code)); }
return builder.str;
}
static string decrypt(string input, int code) {
return encrypt(input, 26 - code);
}
const string test_case = "The quick brown fox jumped over the lazy dog";
void main() {
println(test_case); println(encrypt(test_case, -1)); println(decrypt(encrypt(test_case, -1), -1));
}</lang>
- Output:
The quick brown fox jumped over the lazy dog Sgd pthbj aqnvm enw itlodc nudq sgd kvyx cnf The quick brown fox jumped over the lwzy dog
VBA
<lang vb> Option Explicit
Sub Main_Caesar() Dim ch As String
ch = Caesar_Cipher("CAESAR: Who is it in the press that calls on me? I hear a tongue, shriller than all the music, Cry 'Caesar!' Speak; Caesar is turn'd to hear.", 14) Debug.Print ch Debug.Print Caesar_Cipher(ch, -14)
End Sub
Function Caesar_Cipher(sText As String, lngNumber As Long) As String Dim Tbl, strGlob As String, strTemp As String, i As Long, bytAscii As Byte
Const MAJ As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" Const NB_LETTERS As Byte = 26 Const DIFFASCIIMAJ As Byte = 65 - NB_LETTERS Const DIFFASCIIMIN As Byte = 97 - NB_LETTERS strTemp = sText If lngNumber < NB_LETTERS And lngNumber > NB_LETTERS * -1 Then strGlob = String(NB_LETTERS * 4, " ") LSet strGlob = MAJ & MAJ & MAJ Tbl = Split(StrConv(strGlob, vbUnicode), Chr(0)) For i = 1 To Len(strTemp) If Mid(strTemp, i, 1) Like "[a-zA-Z]" Then bytAscii = Asc(Mid(strTemp, i, 1)) If Mid(strTemp, i, 1) = Tbl(bytAscii - DIFFASCIIMAJ) Then Mid(strTemp, i) = Tbl(bytAscii - DIFFASCIIMAJ + lngNumber) Else Mid(strTemp, i) = LCase(Tbl(bytAscii - DIFFASCIIMIN + lngNumber)) End If End If Next i End If Caesar_Cipher = strTemp
End Function </lang>
- Output:
QOSGOF: Kvc wg wh wb hvs dfsgg hvoh qozzg cb as? W vsof o hcbuis, gvfwzzsf hvob ozz hvs aigwq, Qfm 'Qosgof!' Gdsoy; Qosgof wg hifb'r hc vsof. CAESAR: Who is it in the press that calls on me? I hear a tongue, shriller than all the music, Cry 'Caesar!' Speak; Caesar is turn'd to hear.
Vedit macro language
This implementation ciphers/deciphers a highlighted block of text in-place in current edit buffer. <lang vedit>#10 = Get_Num("Enter the key: positive to cipher, negative to de-cipher: ", STATLINE)
Goto_Pos(Block_Begin) while(Cur_Pos < Block_End) {
#11 = Cur_Char & 0x60 + 1 if (Cur_Char >= 'A') { Ins_Char((Cur_Char - #11 + 26 + #10) % 26 + #11, OVERWRITE) } else {
Char(1)
}
}</lang>
- Output:
with key 13
Original text: Quick brown Fox jumps over the lazy Dog. Encrypted text: Dhvpx oebja Sbk whzcf bire gur ynml Qbt. Decrypted text: Quick brown Fox jumps over the lazy Dog.
vbscript
Note that a left rotation has an equivalent right rotation so all rotations are converted to the equivalent right rotation prior to translation. <lang vbscript> str = "IT WAS THE BEST OF TIMES, IT WAS THE WORST OF TIMES."
Wscript.Echo str Wscript.Echo Rotate(str,5) Wscript.Echo Rotate(Rotate(str,5),-5)
'Rotate (Caesar encrypt/decrypt) test <numpos> positions. ' numpos < 0 - rotate left ' numpos > 0 - rotate right 'Left rotation is converted to equivalent right rotation
Function Rotate (text, numpos)
dim dic: set dic = CreateObject("Scripting.Dictionary") dim ltr: ltr = Split("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z") dim rot: rot = (26 + numpos Mod 26) Mod 26 'convert all to right rotation dim ch dim i
for i = 0 to ubound(ltr) dic(ltr(i)) = ltr((rot+i) Mod 26) next
Rotate = ""
for i = 1 to Len(text) ch = Mid(text,i,1) if dic.Exists(ch) Then Rotate = Rotate & dic(ch) else Rotate = Rotate & ch end if next
End Function </lang>
- Output:
D:\script>Caesar.vbs IT WAS THE BEST OF TIMES, IT WAS THE WORST OF TIMES. NY BFX YMJ GJXY TK YNRJX, NY BFX YMJ BTWXY TK YNRJX. IT WAS THE BEST OF TIMES, IT WAS THE WORST OF TIMES.
Wortel
<lang wortel>@let {
; this function only replaces letters and keeps case ceasar &[s n] !!s.replace &"[a-z]"gi &[x] [ @vars { t x.charCodeAt. l ?{ && > t 96 < t 123 97 && > t 64 < t 91 65 0 } } !String.fromCharCode ?{ l +l ~% 26 -+ n t l t } ] !!ceasar "abc $%^ ABC" 10
}</lang> Returns:
"klm $%^ KLM"
XLISP
<lang lisp>(defun caesar-encode (text key)
(defun encode (ascii-code) (defun rotate (character alphabet) (define code (+ character key)) (cond ((> code (+ alphabet 25)) (- code 26)) ((< code alphabet) (+ code 26)) (t code))) (cond ((and (>= ascii-code 65) (<= ascii-code 90)) (rotate ascii-code 65)) ((and (>= ascii-code 97) (<= ascii-code 122)) (rotate ascii-code 97)) (t ascii-code))) (list->string (mapcar integer->char (mapcar encode (mapcar char->integer (string->list text))))))
(defun caesar-decode (text key)
(caesar-encode text (- 26 key)))</lang>
Test it in a REPL: <lang lisp>[1] (define caesar-test (caesar-encode "CAESAR: Who is it in the press that calls on me? I hear a tongue, shriller than all the music, Cry 'Caesar!' Speak; Caesar is turn'd to hear." 14))
CAESAR-TEST [2] caesar-test
"QOSGOF: Kvc wg wh wb hvs dfsgg hvoh qozzg cb as? W vsof o hcbuis, gvfwzzsf hvob ozz hvs aigwq, Qfm 'Qosgof!' Gdsoy; Qosgof wg hifb'r hc vsof." [3] (caesar-decode caesar-test 14)
"CAESAR: Who is it in the press that calls on me? I hear a tongue, shriller than all the music, Cry 'Caesar!' Speak; Caesar is turn'd to hear."</lang>
XPL0
To decrypt a message use the negative value of the encrypting key. Usage: caesar key <infile.txt >outfile.xxx
<lang XPL0>code ChIn=7, ChOut=8, IntIn=10; int Key, C; [Key:= IntIn(8); repeat C:= ChIn(1);
if C>=^a & C<=^z then C:= C-$20; if C>=^A & C<=^Z then [C:= C+Key; if C>^Z then C:= C-26 else if C<^A then C:= C+26; ]; ChOut(0, C);
until C=$1A; \EOF ]</lang>
Example outfile.xxx:
SDFN PB ERA ZLWK ILYH GRCHQ OLTXRU MXJV.
zkl
<lang zkl>fcn caesarCodec(str,n,encode=True){
var [const] letters=["a".."z"].chain(["A".."Z"]).pump(String); // static if(not encode) n=26 - n; m,sz := n + 26, 26 - n; ltrs:=String(letters[n,sz],letters[0,n],letters[m,sz],letters[26,n]); str.translate(letters,ltrs)
}</lang> <lang zkl>text:="The five boxing wizards jump quickly"; N:=3; code:=caesarCodec(text,N); println("text = ",text); println("encoded(%d) = %s".fmt(N,code)); println("decoded = ",caesarCodec(code,N,False));</lang>
- Output:
text = The five boxing wizards jump quickly encoded(3) = Wkh ilyh eralqj zlcdugv mxps txlfnob decoded = The five boxing wizards jump quickly
zonnon
<lang zonnon> module Caesar; const size = 25;
type Operation = (code,decode);
procedure C_D(s:string;k:integer;op: Operation): string; var i,key: integer; resp: string; n,c: char; begin resp := ""; if op = Operation.decode then key := k else key := (26 - k) end; for i := 0 to len(s) - 1 do c := cap(s[i]); if (c >= 'A') & (c <= 'Z') then resp := resp + string(char(integer('A') + ((integer(c) - integer('A') + key )) mod 26)); else resp := resp + string(c) end; end; return resp end C_D;
procedure {public} Cipher(s:string;k:integer):string; var i: integer; resp: string; n,c: char; begin return C_D(s,k,Operation.code) end Cipher;
procedure {public} Decipher(s:string;k:integer):string; var i: integer; resp: string; n,c: char; begin return C_D(s,k,Operation.decode) end Decipher;
var txt,cipher,decipher: string;
begin txt := "HI";cipher := Caesar.Cipher(txt,2);decipher := Caesar.Decipher(cipher,2); writeln(txt," -c-> ",cipher," -d-> ",decipher); txt := "ZA";cipher := Caesar.Cipher(txt,2);decipher := Caesar.Decipher(cipher,2); writeln(txt," -c-> ",cipher," -d-> ",decipher); txt := "The five boxing wizards jump quickly"; cipher := Caesar.Cipher(txt,2);decipher := Caesar.Decipher(cipher,2); writeln(txt," -c-> ",cipher," -d-> ",decipher) end Caesar. </lang>
- Output:
HI -c-> FG -d-> HI ZA -c-> XY -d-> ZA The five boxing wizards jump quickly -c-> RFC DGTC ZMVGLE UGXYPBQ HSKN OSGAIJW -d-> THE FIVE BOXING WIZARDS JUMP QUICKLY
ZX Spectrum Basic
<lang zxbasic>10 LET t$="PACK MY BOX WITH FIVE DOZEN LIQUOR JUGS" 20 PRINT t$ 30 LET key=RND*25+1 40 LET k=key: GO SUB 1000: PRINT t$ 50 LET k=26-key: GO SUB 1000: PRINT t$ 60 STOP 1000 FOR i=1 TO LEN t$ 1010 LET c= CODE t$(i) 1020 IF c<65 OR c>90 THEN GO TO 1050 1030 LET c=c+k: IF c>90 THEN LET c=c-90+64 1040 LET t$(i)=CHR$ c 1050 NEXT i 1060 RETURN </lang>
- Programming Tasks
- Encryption
- String manipulation
- 8th
- Ada
- ALGOL 68
- APL
- Applesoft BASIC
- Astro
- AutoHotkey
- AutoIt
- AWK
- Babel
- BaCon
- BBC BASIC
- Befunge
- C
- C++
- C sharp
- Clojure
- COBOL
- CoffeeScript
- Common Lisp
- Crystal
- Cubescript
- D
- Dart
- Eiffel
- Ela
- Elena
- Elixir
- Erlang
- ERRE
- Euphoria
- F Sharp
- Fantom
- Forth
- Fortran
- FreeBASIC
- Gambas
- GAP
- GFA Basic
- Go
- Groovy
- Haskell
- Icon
- Unicon
- J
- Java
- JavaScript
- Julia
- K
- Kotlin
- LabVIEW
- Liberty BASIC
- LiveCode
- Logo
- Lua
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Octave
- ML
- MLite
- NetRexx
- Nim
- Oberon-2
- Objeck
- OCaml
- Oforth
- OOC
- PARI/GP
- Pascal
- Perl
- Perl 6
- Phix
- PHP
- PicoLisp
- PL/I
- PowerShell
- Prolog
- Clpfd
- PureBasic
- Python
- R
- Racket
- Retro
- REXX
- Ring
- Ruby
- Run BASIC
- Rust
- Scala
- Scheme
- Sed
- Seed7
- SequenceL
- Sidef
- Sinclair ZX81 BASIC
- Smalltalk
- SSEM
- Stata
- Swift
- Tcl
- TUSCRIPT
- TXR
- TypeScript
- UNIX Shell
- Ursa
- Ursala
- Vala
- VBA
- Vedit macro language
- Vbscript
- Wortel
- XLISP
- XPL0
- Zkl
- Zonnon
- ZX Spectrum Basic
- GUISS/Omit