Vigenère cipher: Difference between revisions
m →{{header|Wren}}: Minor tidy |
|||
(135 intermediate revisions by 69 users not shown) | |||
Line 1: | Line 1: | ||
{{task|Encryption}} |
{{task|Encryption}} |
||
[[Category:String manipulation]] |
|||
{{omit from|GUISS|would need to install an application that could do this}} |
|||
{{omit from|Openscad}} |
|||
;Task: |
|||
Implement a [[wp:Vigen%C3%A8re_cipher|Vigenère cypher]], both encryption and decryption. The program should handle keys and text of unequal length, and should capitalize everything and discard non-alphabetic characters. (If your program handles non-alphabetic characters in another way, make a note of it.) |
|||
Implement a [[wp:Vigen%C3%A8re_cipher|Vigenère cypher]], both encryption and decryption. |
|||
The program should handle keys and text of unequal length, |
|||
See also: |
|||
and should capitalize everything and discard non-alphabetic characters. <br> |
|||
* [[Vigenère Cipher/Cryptanalysis]] |
|||
(If your program handles non-alphabetic characters in another way, |
|||
make a note of it.) |
|||
=={{header|Ada}}== |
|||
;Related tasks: |
|||
<lang Ada>with Ada.Text_IO; |
|||
* [[Caesar cipher]] |
|||
* [[Rot-13]] |
|||
* [[Substitution Cipher]] |
|||
<br><br> |
|||
=={{header|11l}}== |
|||
procedure Vignere_Cipher is |
|||
{{trans|C++}} |
|||
<syntaxhighlight lang="11l">F encrypt(key, text) |
|||
subtype Letter is Character range 'A' .. 'Z'; |
|||
V out = ‘’ |
|||
subtype Lowercase is Character range 'a' .. 'z'; |
|||
V j = 0 |
|||
L(c) text |
|||
I !c.is_alpha() |
|||
L.continue |
|||
out ‘’= Char(code' (c.uppercase().code + key[j].code - 2 * ‘A’.code) % 26 + ‘A’.code) |
|||
j = (j + 1) % key.len |
|||
R out |
|||
F decrypt(key, text) |
|||
function "+"(X, Y: Letter) return Letter is |
|||
V out = ‘’ |
|||
begin |
|||
V j = 0 |
|||
return Character'Val( ( (Character'Pos(X)-Character'Pos('A')) |
|||
L(c) text |
|||
+ (Character'Pos(Y)-Character'Pos('A')) ) mod 26 |
|||
I !c.is_alpha() |
|||
+ Character'Pos('A')); |
|||
L.continue |
|||
end; |
|||
out ‘’= Char(code' (c.code - key[j].code + 26) % 26 + ‘A’.code) |
|||
j = (j + 1) % key.len |
|||
R out |
|||
V key = ‘VIGENERECIPHER’ |
|||
function Normalize(S: String) return String is |
|||
V original = ‘Beware the Jabberwock, my son! The jaws that bite, the claws that catch!’ |
|||
-- removes all characters except for uppercase and lowercase letters |
|||
V encrypted = encrypt(key, original) |
|||
-- replaces lowercase by uppercase letters |
|||
V decrypted = decrypt(key, encrypted) |
|||
Offset: Integer := Character'Pos('A') - Character'Pos('a'); |
|||
begin |
|||
if S="" then |
|||
return ""; |
|||
elsif S(S'First) in Letter then |
|||
return S(S'First) & Normalize(S(S'First+1 .. S'Last)); |
|||
elsif S(S'First) in Lowercase then |
|||
return (Character'Val(Character'Pos(S(S'First)) + Offset) |
|||
& Normalize(S(S'First+1 .. S'Last))); |
|||
else |
|||
return Normalize(S(S'First+1 .. S'Last)); |
|||
end if; |
|||
end Normalize; |
|||
print(original) |
|||
function Encrypt(Key: String; Text: String) return String is |
|||
print(‘Encrypted: ’encrypted) |
|||
Ciphertext: String(Text'Range); |
|||
print(‘Decrypted: ’decrypted)</syntaxhighlight> |
|||
begin |
|||
for I in Text'Range loop |
|||
Ciphertext(I) := Text(I) |
|||
+ Key(Key'First + ((I-Text'First) mod Key'Length)); |
|||
end loop; |
|||
return Ciphertext; |
|||
end Encrypt; |
|||
{{out}} |
|||
function Invert(Key: String) return String is |
|||
<pre> |
|||
Result: String(Key'Range); |
|||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
begin |
|||
Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
for I in Key'Range loop |
|||
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
Result(I) |
|||
</pre> |
|||
:= Character'Val( 26 - (Character'Pos(Key(I))-Character'Pos('A')) |
|||
+ Character'Pos('A') ); |
|||
end loop; |
|||
return Result; |
|||
end Invert; |
|||
=={{header|Action!}}== |
|||
use Ada.Text_IO; |
|||
<syntaxhighlight lang="action!">PROC Fix(CHAR ARRAY in,fixed) |
|||
Input: String := Get_Line; |
|||
INT i |
|||
Key: String := Normalize(Get_Line); |
|||
CHAR c |
|||
Ciph: String := Encrypt(Key => Key, Text => Normalize(Input)); |
|||
fixed(0)=0 |
|||
begin |
|||
FOR i=1 TO in(0) |
|||
Put_Line("Input =" & Input); |
|||
DO |
|||
Put_Line("Key =" & Key); |
|||
c=in(i) |
|||
Put_Line("Ciphertext =" & Ciph); |
|||
IF c>='a AND c<='z THEN |
|||
Put_Line("Decryption =" & Encrypt(Key => Invert(Key), Text => Ciph)); |
|||
c==-('a-'A) |
|||
end Vignere_Cipher;</lang> |
|||
FI |
|||
IF c>='A AND c<='Z THEN |
|||
fixed(0)==+1 |
|||
fixed(fixed(0))=c |
|||
FI |
|||
OD |
|||
RETURN |
|||
PROC Process(CHAR ARRAY in,key,out INT dir) |
|||
Output |
|||
CHAR ARRAY inFixed(256),keyFixed(256) |
|||
INT keyI,tmp,i |
|||
CHAR c |
|||
out(0)=0 |
|||
<pre>./vignere_cipher < input.txt |
|||
Fix(in,inFixed) |
|||
Input =Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
Fix(key,keyFixed) |
|||
Key =VIGENERECIPHER |
|||
IF inFixed(0)=0 OR keyFixed(0)=0 THEN |
|||
Ciphertext =WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
RETURN |
|||
Decryption =BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
|||
FI |
|||
keyI=1 |
|||
FOR i=1 TO inFixed(0) |
|||
DO |
|||
c=inFixed(i) |
|||
tmp=c-'A+dir*(keyFixed(keyI)-'A) |
|||
IF tmp<0 THEN |
|||
tmp==+26 |
|||
FI |
|||
out(0)==+1 |
|||
out(out(0))='A+tmp MOD 26 |
|||
keyI==+1 |
|||
IF keyI>keyFixed(0) THEN |
|||
keyI=1 |
|||
FI |
|||
OD |
|||
RETURN |
|||
PROC Encrypt(CHAR ARRAY in,key,out) |
|||
Process(in,key,out,1) |
|||
RETURN |
|||
PROC Decrypt(CHAR ARRAY in,key,out) |
|||
Process(in,key,out,-1) |
|||
RETURN |
|||
PROC Test(CHAR ARRAY in,key) |
|||
CHAR ARRAY enc(256),dec(256) |
|||
PrintE("Original:") PrintE(in) |
|||
Encrypt(in,key,enc) |
|||
PrintF("Encrypted key=%S:%E",key) PrintE(enc) |
|||
Decrypt(enc,key,dec) |
|||
PrintF("Decrypted key=%S:%E",key) PrintE(dec) |
|||
PutE() |
|||
RETURN |
|||
PROC Main() |
|||
Test("Attack at dawn!","LEMONLEMONLE") |
|||
Test("Crypto is short for cryptography.","ABCDABCDABCDABCDABCDABCDABCD") |
|||
RETURN</syntaxhighlight> |
|||
{{out}} |
|||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Vigen%C3%A8re_cipher.png Screenshot from Atari 8-bit computer] |
|||
<pre> |
|||
Original: |
|||
Attack at dawn! |
|||
Encrypted key=LEMONLEMONLE: |
|||
LXFOPVEFRNHR |
|||
Decrypted key=LEMONLEMONLE: |
|||
ATTACKATDAWN |
|||
Original: |
|||
Crypto is short for cryptography. |
|||
Encrypted key=ABCDABCDABCDABCDABCDABCDABCD: |
|||
CSASTPKVSIQUTGQUCSASTPIUAQJB |
|||
Decrypted key=ABCDABCDABCDABCDABCDABCDABCD: |
|||
CRYPTOISSHORTFORCRYPTOGRAPHY |
|||
</pre> |
|||
=={{header|Ada}}== |
|||
<syntaxhighlight lang="ada">WITH Ada.Text_IO, Ada.Characters.Handling; |
|||
USE Ada.Text_IO, Ada.Characters.Handling; |
|||
PROCEDURE Main IS |
|||
SUBTYPE Alpha IS Character RANGE 'A' .. 'Z'; |
|||
TYPE Ring IS MOD (Alpha'Range_length); |
|||
TYPE Seq IS ARRAY (Integer RANGE <>) OF Ring; |
|||
FUNCTION "+" (S, Key : Seq) RETURN Seq IS |
|||
R : Seq (S'Range); |
|||
BEGIN |
|||
FOR I IN R'Range LOOP |
|||
R (I) := S (I) + Key (Key'First + (I - R'First) MOD Key'Length); |
|||
END LOOP; |
|||
RETURN R; |
|||
END "+"; |
|||
FUNCTION "-" (S : Seq) RETURN Seq IS |
|||
R : Seq (S'Range); |
|||
BEGIN |
|||
FOR I IN R'Range LOOP |
|||
R (I) := - S (I); |
|||
END LOOP; |
|||
RETURN R; |
|||
END "-"; |
|||
FUNCTION To_Seq (S : String) RETURN Seq IS |
|||
R : Seq (S'Range); |
|||
I : Integer := R'First; |
|||
BEGIN |
|||
FOR C OF To_Upper (S) LOOP |
|||
IF C IN Alpha THEN |
|||
R (I) := Ring'Mod (Alpha'Pos (C) - Alpha'Pos (Alpha'First)); |
|||
I := I + 1; |
|||
END IF; |
|||
END LOOP; |
|||
RETURN R (R'First .. I - 1); |
|||
END To_Seq; |
|||
FUNCTION To_String (S : Seq ) RETURN String IS |
|||
R : String (S'Range); |
|||
BEGIN |
|||
FOR I IN R'Range LOOP |
|||
R (I) := Alpha'Val ( Integer (S (I)) + Alpha'Pos (Alpha'First)); |
|||
END LOOP; |
|||
RETURN R; |
|||
END To_String; |
|||
Input : Seq := To_Seq (Get_Line); |
|||
Key : Seq := To_Seq (Get_Line); |
|||
Crypt : Seq := Input + Key; |
|||
BEGIN |
|||
Put_Line ("Encrypted: " & To_String (Crypt)); |
|||
Put_Line ("Decrypted: " & To_String (Crypt + (-Key))); |
|||
END Main; |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
VIGENERECIPHER |
|||
Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
|||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
Line 85: | Line 219: | ||
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny].}} |
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny].}} |
||
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d].}} |
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d].}} |
||
< |
<syntaxhighlight lang="algol68">STRING key := ""; |
||
PROC vigenere cipher = (REF STRING key)VOID: |
PROC vigenere cipher = (REF STRING key)VOID: |
||
Line 146: | Line 280: | ||
print(("Encrypted: ", encrypted, new line)); |
print(("Encrypted: ", encrypted, new line)); |
||
print(("Decrypted: ", decrypted, new line)) |
print(("Decrypted: ", decrypted, new line)) |
||
)</ |
)</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
||
Line 153: | Line 287: | ||
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
||
</pre> |
</pre> |
||
=={{header|Applesoft BASIC}}== |
|||
Lines <code>340,350,430,440</code> could probably been put into some DEF FN, but it would probably have made it harder to read. The maximum length for a string in AppleSoft BASIC is 255 characters. |
|||
I have not used the DEF FN MOD(A) function in line <code>450</code> on purpose, as I still would have had to correct for a possible negative value. |
|||
<syntaxhighlight lang="applesoft basic"> |
|||
100 : |
|||
110 REM VIGENERE CIPHER |
|||
120 : |
|||
200 REM SET-UP |
|||
210 K$ = "LEMON": PRINT "KEY: "; K$ |
|||
220 PT$ = "ATTACK AT DAWN": PRINT "PLAIN TEXT: ";PT$ |
|||
230 DEF FN MOD(A) = A - INT (A / 26) * 26 |
|||
300 REM ENCODING |
|||
310 K = 1 |
|||
320 FOR I = 1 TO LEN (PT$) |
|||
330 IF ASC ( MID$ (PT$,I,1)) < 65 |
|||
OR ASC ( MID$ (PT$,I,1)) > 90 THEN NEXT I |
|||
340 TV = ASC ( MID$ (PT$,I,1)) - 65 |
|||
350 KV = ASC ( MID$ (K$,K,1)) - 65 |
|||
360 CT$ = CT$ + CHR$ ( FN MOD(TV + KV) + 65) |
|||
370 K = K + 1: IF K > LEN (K$) THEN K = 1 |
|||
380 NEXT I |
|||
390 PRINT "CIPHER TEXT: ";CT$ |
|||
400 REM DECODING |
|||
410 K = 1 |
|||
420 FOR I = 1 TO LEN (CT$) |
|||
430 TV = ASC ( MID$ (CT$,I,1)) - 65 |
|||
440 KV = ASC ( MID$ (K$,K,1)) - 65 |
|||
450 T = TV - KV: IF T < 0 THEN T = T + 26 |
|||
460 DT$ = DT$ + CHR$ (T + 65) |
|||
470 K = K + 1: IF K > LEN (K$) THEN K = 1 |
|||
480 NEXT I |
|||
490 PRINT "DECRYPTED TEXT: ";DT$ </syntaxhighlight> |
|||
{{out}} |
|||
KEY: LEMON |
|||
PLAIN TEXT: ATTACK AT DAWN |
|||
CIPHER TEXT: LXFOPVEFRNHR |
|||
DECRYPTED TEXT: ATTACKATDAWN |
|||
=={{header|Arturo}}== |
|||
<syntaxhighlight lang="rebol">Letters: append `A`..`Z` `a`..`z` |
|||
encrypt: function [msg, key][ |
|||
pos: 0 |
|||
result: new "" |
|||
loop msg 'c -> |
|||
if in? c Letters [ |
|||
'result ++ to :char (((to :integer key\[pos]) + to :integer upper c) % 26) + to :integer `A` |
|||
pos: (pos + 1) % size key |
|||
] |
|||
return result |
|||
] |
|||
decrypt: function [msg, key][ |
|||
pos: 0 |
|||
result: new "" |
|||
loop msg 'c [ |
|||
'result ++ to :char ((26 + (to :integer c) - to :integer key\[pos]) % 26) + to :integer `A` |
|||
pos: (pos + 1) % size key |
|||
] |
|||
return result |
|||
] |
|||
text: "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
key: "VIGENERECIPHER" |
|||
encr: encrypt text key |
|||
decr: decrypt encr key |
|||
print text |
|||
print encr |
|||
print decr</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
< |
<syntaxhighlight lang="autohotkey">Key = VIGENERECIPHER |
||
Text= Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
Text= Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
||
Line 177: | Line 389: | ||
decoderKey .= Chr(26-(Asc(A_LoopField)-65)+65) |
decoderKey .= Chr(26-(Asc(A_LoopField)-65)+65) |
||
return VigenereCipher(Text, decoderKey) |
return VigenereCipher(Text, decoderKey) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre>Input =Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
<pre>Input =Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
||
key =VIGENERECIPHER |
key =VIGENERECIPHER |
||
Ciphertext =WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
Ciphertext =WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
Decrypted =BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
Decrypted =BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
||
=={{header|BASIC256}}== |
|||
{{trans|FreeBASIC}} |
|||
<syntaxhighlight lang="basic256"> |
|||
function Filtrar(cadorigen) |
|||
filtrado = "" |
|||
for i = 1 to length(cadorigen) |
|||
letra = upper(mid(cadorigen, i, 1)) |
|||
if instr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", letra) then filtrado += letra |
|||
next i |
|||
return filtrado |
|||
end function |
|||
function Encriptar(texto, llave) |
|||
texto = Filtrar(texto) |
|||
cifrado = "" |
|||
j = 1 |
|||
for i = 1 to length(texto) |
|||
mSS = mid(texto, i, 1) |
|||
m = asc(mSS) - asc("A") |
|||
kSS = mid(llave, j, 1) |
|||
k = asc(kSS) - asc("A") |
|||
j = (j mod length(llave)) + 1 |
|||
c = (m + k) mod 26 |
|||
letra = chr(asc("A") + c) |
|||
cifrado += letra |
|||
next i |
|||
return cifrado |
|||
end function |
|||
function DesEncriptar(texto, llave) |
|||
descifrado = "" |
|||
j = 1 |
|||
for i = 1 to length(texto) |
|||
mSS = mid(texto, i, 1) |
|||
m = asc(mSS) - asc("A") |
|||
kSS = mid(llave, j, 1) |
|||
k = asc(kSS) - asc("A") |
|||
j = (j mod length(llave)) + 1 |
|||
c = (m - k + 26) mod 26 |
|||
letra = chr(asc("A")+c) |
|||
descifrado += letra |
|||
next i |
|||
return descifrado |
|||
end function |
|||
llave = Filtrar("vigenerecipher") |
|||
cadorigen = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
print cadorigen |
|||
print llave |
|||
cadcifrada = Encriptar(cadorigen, llave) |
|||
print " Cifrado: "; cadcifrada |
|||
print "Descifrado: "; DesEncriptar(cadcifrada, llave) |
|||
end |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Igual que la entrada de FreeBASIC. |
|||
</pre> |
|||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
< |
<syntaxhighlight lang="bbcbasic"> key$ = "LEMON" |
||
plaintext$ = "ATTACK AT DAWN" |
plaintext$ = "ATTACK AT DAWN" |
||
ciphertext$ = FNencrypt(plaintext$, key$) |
ciphertext$ = FNencrypt(plaintext$, key$) |
||
Line 224: | Line 498: | ||
IF C% >= 97 IF C% <= 122 MID$(A$,A%,1) = CHR$(C%-32) |
IF C% >= 97 IF C% <= 122 MID$(A$,A%,1) = CHR$(C%-32) |
||
NEXT |
NEXT |
||
= A$</ |
= A$</syntaxhighlight> |
||
{{out}} |
|||
'''Output:''' |
|||
<pre> |
<pre> |
||
Key = "LEMON" |
Key = "LEMON" |
||
Line 232: | Line 506: | ||
Decrypted = "ATTACKATDAWN" |
Decrypted = "ATTACKATDAWN" |
||
</pre> |
</pre> |
||
=={{header|Befunge}}== |
|||
The text to encrypt is read from stdin. The key is the string literal at the start of the program. |
|||
<syntaxhighlight lang="befunge">"VIGENERECIPHER">>>>1\:!v>"A"-\:00p0v |
|||
>>!#:0#-0#1g#,*#<+:v:-1$_^#!:\+1g00p< |
|||
\"{"\v>9+2*%"A"+^>$>~>:48*\`#@_::"`"` |
|||
*84*`<^4+"4"+g0\_^#!+`*55\`\0::-"A"-*</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY</pre> |
|||
The decrypter is essentially identical, except for a change of sign on the last line. |
|||
<syntaxhighlight lang="befunge">"VIGENERECIPHER">>>>1\:!v>"A"-\:00p0v |
|||
>>!#:0#-0#1g#,*#<+:v:-1$_^#!:\+1g00p< |
|||
\"{"\v>9+2*%"A"+^>$>~>:48*\`#@_::"`"` |
|||
*84*`<^4+"4"-g0\_^#!+`*55\`\0::-"A"-*</syntaxhighlight> |
|||
{{out}} |
|||
<pre>WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
|||
=={{header|C}}== |
=={{header|C}}== |
||
This program skips non-alphabetical characters, preserves case, and when run with the <code>-d</code> command line flag, decrypts the message rather than encrypting. |
|||
<lang C>#include <stdio.h> |
|||
<syntaxhighlight lang="c">#include <stdio.h> |
|||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <string.h> |
#include <string.h> |
||
#include <stdbool.h> |
|||
#include <ctype.h> |
#include <ctype.h> |
||
#include <getopt.h> |
|||
#define NUMLETTERS 26 |
|||
void upper_case(char *src) |
|||
#define BUFSIZE 4096 |
|||
char *get_input(void); |
|||
int main(int argc, char *argv[]) |
|||
{ |
{ |
||
char const usage[] = "Usage: vinigere [-d] key"; |
|||
char sign = 1; |
|||
if (islower(*src)) *src &= ~0x20; |
|||
char const plainmsg[] = "Plain text: "; |
|||
char const cryptmsg[] = "Cipher text: "; |
|||
bool encrypt = true; |
|||
int opt; |
|||
while ((opt = getopt(argc, argv, "d")) != -1) { |
|||
switch (opt) { |
|||
case 'd': |
|||
sign = -1; |
|||
encrypt = false; |
|||
break; |
|||
default: |
|||
fprintf(stderr, "Unrecogized command line argument:'-%i'\n", opt); |
|||
fprintf(stderr, "\n%s\n", usage); |
|||
return 1; |
|||
} |
} |
||
} |
|||
} |
|||
if (argc - optind != 1) { |
|||
char* encipher(const char *src, char *key, int is_encode) |
|||
fprintf(stderr, "%s requires one argument and one only\n", argv[0]); |
|||
{ |
|||
fprintf(stderr, "\n%s\n", usage); |
|||
return 1; |
|||
} |
|||
dest = strdup(src); |
|||
upper_case(dest); |
|||
upper_case(key); |
|||
// Convert argument into array of shifts |
|||
/* strip out non-letters */ |
|||
char const *const restrict key = argv[optind]; |
|||
for (i = 0, slen = 0; dest[slen] != '\0'; slen++) |
|||
size_t const keylen = strlen(key); |
|||
if (isupper(dest[slen])) |
|||
char shifts[keylen]; |
|||
dest[i++] = dest[slen]; |
|||
char const *restrict plaintext = NULL; |
|||
dest[slen = i] = '\0'; /* null pad it, make it safe to use */ |
|||
for (size_t i = 0; i < keylen; i++) { |
|||
if (!(isalpha(key[i]))) { |
|||
fprintf(stderr, "Invalid key\n"); |
|||
return 2; |
|||
} |
|||
char const charcase = (isupper(key[i])) ? 'A' : 'a'; |
|||
// If decrypting, shifts will be negative. |
|||
// This line would turn "bacon" into {1, 0, 2, 14, 13} |
|||
shifts[i] = (key[i] - charcase) * sign; |
|||
} |
|||
do { |
|||
klen = strlen(key); |
|||
fflush(stdout); |
|||
// Print "Plain text: " if encrypting and "Cipher text: " if |
|||
// decrypting |
|||
printf("%s", (encrypt) ? plainmsg : cryptmsg); |
|||
? dest[i] - 'A' + key[i % klen] - 'A' |
|||
plaintext = get_input(); |
|||
: dest[i] - key[i % klen] + 26) % 26; |
|||
if (plaintext == NULL) { |
|||
fprintf(stderr, "Error getting input\n"); |
|||
return 4; |
|||
} |
} |
||
} while (strcmp(plaintext, "") == 0); // Reprompt if entry is empty |
|||
size_t const plainlen = strlen(plaintext); |
|||
return dest; |
|||
char* const restrict ciphertext = calloc(plainlen + 1, sizeof *ciphertext); |
|||
if (ciphertext == NULL) { |
|||
fprintf(stderr, "Memory error\n"); |
|||
return 5; |
|||
} |
|||
for (size_t i = 0, j = 0; i < plainlen; i++) { |
|||
// Skip non-alphabetical characters |
|||
if (!(isalpha(plaintext[i]))) { |
|||
ciphertext[i] = plaintext[i]; |
|||
continue; |
|||
} |
|||
// Check case |
|||
char const charcase = (isupper(plaintext[i])) ? 'A' : 'a'; |
|||
// Wrapping conversion algorithm |
|||
ciphertext[i] = ((plaintext[i] + shifts[j] - charcase + NUMLETTERS) % NUMLETTERS) + charcase; |
|||
j = (j+1) % keylen; |
|||
} |
|||
ciphertext[plainlen] = '\0'; |
|||
printf("%s%s\n", (encrypt) ? cryptmsg : plainmsg, ciphertext); |
|||
free(ciphertext); |
|||
// Silence warnings about const not being maintained in cast to void* |
|||
free((char*) plaintext); |
|||
return 0; |
|||
} |
} |
||
char *get_input(void) { |
|||
char *const restrict buf = malloc(BUFSIZE * sizeof (char)); |
|||
int main() |
|||
if (buf == NULL) { |
|||
return NULL; |
|||
} |
|||
fgets(buf, BUFSIZE, stdin); |
|||
// Get rid of newline |
|||
size_t const len = strlen(buf); |
|||
if (buf[len - 1] == '\n') buf[len - 1] = '\0'; |
|||
return buf; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>$ ./vigenere VIGENERECIPHER |
|||
Plain text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
Cipher text: Wmceei klg Rpifvmeugx, qp wqv! Ioi avey xuek fkbt, alv xtgaf xyev kpagy! |
|||
$ ./vigenere -d VIGENERECIPHER |
|||
Cipher text: Wmceei klg Rpifvmeugx, qp wqv! Ioi avey xuek fkbt, alv xtgaf xyev kpagy! |
|||
Plain text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch!</pre> |
|||
=={{header|C sharp|C#}}== |
|||
<syntaxhighlight lang="csharp"> |
|||
using System; |
|||
namespace VigenereCipher |
|||
{ |
{ |
||
class VCipher |
|||
const char *str = "Beware the Jabberwock, my son! The jaws that bite, " |
|||
{ |
|||
"the claws that catch!"; |
|||
public string encrypt(string txt, string pw, int d) |
|||
{ |
|||
int pwi = 0, tmp; |
|||
string ns = ""; |
|||
txt = txt.ToUpper(); |
|||
pw = pw.ToUpper(); |
|||
foreach (char t in txt) |
|||
{ |
|||
if (t < 65) continue; |
|||
tmp = t - 65 + d * (pw[pwi] - 65); |
|||
if (tmp < 0) tmp += 26; |
|||
ns += Convert.ToChar(65 + ( tmp % 26) ); |
|||
if (++pwi == pw.Length) pwi = 0; |
|||
} |
|||
return ns; |
|||
} |
|||
}; |
|||
class Program |
|||
cod = encipher(str, key, 1); printf("Code: %s\n", cod); |
|||
{ |
|||
dec = encipher(cod, key, 0); printf("Back: %s\n", dec); |
|||
static void Main(string[] args) |
|||
{ |
|||
VCipher v = new VCipher(); |
|||
string s0 = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!", |
|||
/* free(dec); free(cod); */ /* nah */ |
|||
pw = "VIGENERECIPHER"; |
|||
}</lang>Output:<lang>Text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
Console.WriteLine(s0 + "\n" + pw + "\n"); |
|||
key: VIGENERECIPHER |
|||
string s1 = v.encrypt(s0, pw, 1); |
|||
Code: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
Console.WriteLine("Encrypted: " + s1); |
|||
Back: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</lang> |
|||
s1 = v.encrypt(s1, "VIGENERECIPHER", -1); |
|||
Console.WriteLine("Decrypted: " + s1); |
|||
Console.WriteLine("\nPress any key to continue..."); |
|||
Console.ReadKey(); |
|||
} |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
VIGENERECIPHER |
|||
Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
</pre> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
< |
<syntaxhighlight lang="cpp">#include <iostream> |
||
#include <string> |
#include <string> |
||
using namespace std; |
using namespace std; |
||
Line 367: | Line 784: | ||
cout << "Encrypted: " << encrypted << endl; |
cout << "Encrypted: " << encrypted << endl; |
||
cout << "Decrypted: " << decrypted << endl; |
cout << "Decrypted: " << decrypted << endl; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
||
Line 376: | Line 793: | ||
</pre> |
</pre> |
||
=={{header| |
=={{header|Ceylon}}== |
||
<syntaxhighlight lang="ceylon">shared void run() { |
|||
This doesn't assume anything about character codes other than A-Z being a contiguous block (but still, we could be using EBCDIC. Who knows.) |
|||
<lang lisp>(defun strip (s) |
|||
function normalize(String text) => text.uppercased.filter(Character.letter); |
|||
(remove-if-not |
|||
(lambda (c) (char<= #\A c #\Z)) |
|||
function crypt(String text, String key, Character(Character, Character) transform) => String { |
|||
(string-upcase s))) |
|||
for ([a, b] in zipPairs(normalize(text), normalize(key).cycled)) |
|||
transform(a, b) |
|||
}; |
|||
function encrypt(String clearText, String key) => |
|||
crypt(clearText, key, (Character a, Character b) => |
|||
('A'.integer + ((a.integer + b.integer - 130) % 26)).character); |
|||
function decrypt(String cipherText, String key) => |
|||
(defun vigenère (s key &key decipher |
|||
crypt(cipherText, key, (Character a, Character b) => |
|||
&aux (A (char-code #\A)) |
|||
('A'.integer + ((a.integer - b.integer + 26) % 26)).character); |
|||
(op (if decipher #'- #'+))) |
|||
value key = "VIGENERECIPHER"; |
|||
((to-char (c) (code-char (+ c A))) |
|||
value message = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"; |
|||
(to-code (c) (- (char-code c) A))) |
|||
value encrypted = encrypt(message, key); |
|||
(let ((k (map 'list #'to-code (strip key)))) |
|||
value decrypted = decrypt(encrypted, key); |
|||
(setf (cdr (last k)) k) |
|||
print(encrypted); |
|||
print(decrypted); |
|||
}</syntaxhighlight> |
|||
(to-char |
|||
(mod (funcall op (to-code c) (car k)) 26)) |
|||
(setf k (cdr k)))) |
|||
(strip s))))) |
|||
(let* ((msg "Beware the Jabberwock... The jaws that... the claws that catch!") |
|||
(key "vigenere cipher") |
|||
(enc (vigenère msg key)) |
|||
(dec (vigenère enc key :decipher t))) |
|||
(format t "msg: ~a~%enc: ~a~%dec: ~a~%" msg enc dec))</lang>output<lang>msg: Beware the Jabberwock... The jaws that... the claws that catch! |
|||
enc: WMCEEIKLGRPIFVMEUGXXYILILZXYVBZLRGCEYAIOEKXIZGU |
|||
dec: BEWARETHEJABBERWOCKTHEJAWSTHATTHECLAWSTHATCATCH</lang> |
|||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
Requires Clojure 1.2. |
Requires Clojure 1.2. |
||
< |
<syntaxhighlight lang="clojure">(ns org.rosettacode.clojure.vigenere |
||
(:require [clojure.string :as string])) |
(:require [clojure.string :as string])) |
||
Line 437: | Line 850: | ||
; decipher a text |
; decipher a text |
||
(defn decrypt [ciphertext key] (crypt #'- ciphertext key))</ |
(defn decrypt [ciphertext key] (crypt #'- ciphertext key))</syntaxhighlight> |
||
Demonstration code: |
Demonstration code: |
||
< |
<syntaxhighlight lang="clojure">(ns org.rosettacode.clojure.test-vigenere |
||
(:require [org.rosettacode.clojure.vigenere :as vigenere])) |
(:require [org.rosettacode.clojure.vigenere :as vigenere])) |
||
Line 451: | Line 864: | ||
(doall (map (fn [[k v]] (printf "%9s: %s\n" k v)) |
(doall (map (fn [[k v]] (printf "%9s: %s\n" k v)) |
||
[ ["Original" plaintext] ["Key" key] ["Encrypted" ciphertext] ["Decrypted" recovered] ]))) |
[ ["Original" plaintext] ["Key" key] ["Encrypted" ciphertext] ["Decrypted" recovered] ]))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
|||
Output: |
|||
<pre> Original: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
<pre> Original: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
||
Key: Vigenere cipher |
Key: Vigenere cipher |
||
Line 461: | Line 874: | ||
=={{header|CoffeeScript}}== |
=={{header|CoffeeScript}}== |
||
{{trans|D}} |
{{trans|D}} |
||
< |
<syntaxhighlight lang="coffeescript"># Simple helper since charCodeAt is quite long to write. |
||
code = (char) -> char.charCodeAt() |
code = (char) -> char.charCodeAt() |
||
Line 495: | Line 908: | ||
console.log "Original : #{original}" |
console.log "Original : #{original}" |
||
console.log "Encrypted : #{encrypted}" |
console.log "Encrypted : #{encrypted}" |
||
console.log "Decrypted : #{decrypt encrypted, key}"</ |
console.log "Decrypted : #{decrypt encrypted, key}"</syntaxhighlight> |
||
<pre>Original : Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
<pre>Original : Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
||
Encrypted : WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
Encrypted : WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
Decrypted : BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
Decrypted : BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
||
=={{header|Common Lisp}}== |
|||
====Main version==== |
|||
This doesn't assume anything about character codes other than A-Z being a contiguous block (but still, we could be using EBCDIC. Who knows.) |
|||
<syntaxhighlight lang="lisp">(defun strip (s) |
|||
(remove-if-not |
|||
(lambda (c) (char<= #\A c #\Z)) |
|||
(string-upcase s))) |
|||
(defun vigenère (s key &key decipher |
|||
&aux (A (char-code #\A)) |
|||
(op (if decipher #'- #'+))) |
|||
(labels |
|||
((to-char (c) (code-char (+ c A))) |
|||
(to-code (c) (- (char-code c) A))) |
|||
(let ((k (map 'list #'to-code (strip key)))) |
|||
(setf (cdr (last k)) k) |
|||
(map 'string |
|||
(lambda (c) |
|||
(prog1 |
|||
(to-char |
|||
(mod (funcall op (to-code c) (car k)) 26)) |
|||
(setf k (cdr k)))) |
|||
(strip s))))) |
|||
(let* ((msg "Beware the Jabberwock... The jaws that... the claws that catch!") |
|||
(key "vigenere cipher") |
|||
(enc (vigenère msg key)) |
|||
(dec (vigenère enc key :decipher t))) |
|||
(format t "msg: ~a~%enc: ~a~%dec: ~a~%" msg enc dec))</syntaxhighlight> |
|||
{{out}} |
|||
<pre>msg: Beware the Jabberwock... The jaws that... the claws that catch! |
|||
enc: WMCEEIKLGRPIFVMEUGXXYILILZXYVBZLRGCEYAIOEKXIZGU |
|||
dec: BEWARETHEJABBERWOCKTHEJAWSTHATTHECLAWSTHATCATCH</pre> |
|||
====Alternate version==== |
|||
No string to circular list conversion here. |
|||
1. Program |
|||
<syntaxhighlight lang="lisp">(defconstant +a+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ") |
|||
(defun strip (s) |
|||
(string-upcase (remove-if-not 'alpha-char-p s))) |
|||
(defun vigenere (txt key &key plain &aux (p (if plain -1 1))) |
|||
(let ((txt (strip txt)) (key (strip key)) (i -1)) |
|||
(map 'string |
|||
(lambda (c) |
|||
(setf i (mod (1+ i) (length key))) |
|||
(char +a+ (mod (+ (position c +a+) (* p (position (elt key i) +a+))) 26))) |
|||
txt)))</syntaxhighlight> |
|||
2. Execution |
|||
<pre>(vigenere "« Through the Looking-Glass »" "Lewis Carroll") |
|||
(vigenere "ELNWMIHKYSWZZOEVYILRJG" "Lewis Carroll" :plain t)</pre> |
|||
{{out}} |
|||
<pre> |
|||
"ELNWMIHKYSWZZOEVYILRJG" |
|||
"THROUGHTHELOOKINGGLASS"</pre> |
|||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">import std.stdio, std.string; |
||
string encrypt(in string txt, in string key) pure |
string encrypt(in string txt, in string key) pure @safe |
||
in { |
in { |
||
assert(key.removechars("^A-Z") == key); |
assert(key.removechars("^A-Z") == key); |
||
} body { |
} body { |
||
string res; |
string res; |
||
foreach (immutable i, immutable c; |
foreach (immutable i, immutable c; txt.toUpper.removechars("^A-Z")) |
||
res ~= (c + key[i % $] - 2 * 'A') % 26 + 'A'; |
res ~= (c + key[i % $] - 2 * 'A') % 26 + 'A'; |
||
return res; |
return res; |
||
} |
} |
||
string decrypt(in string txt, in string key) pure |
string decrypt(in string txt, in string key) pure @safe |
||
in { |
in { |
||
assert(key.removechars("^A-Z") == key); |
assert(key.removechars("^A-Z") == key); |
||
} body { |
} body { |
||
string res; |
string res; |
||
foreach (immutable i, immutable c; |
foreach (immutable i, immutable c; txt.toUpper.removechars("^A-Z")) |
||
res ~= (c - key[i % $] + 26) % 26 + 'A'; |
res ~= (c - key[i % $] + 26) % 26 + 'A'; |
||
return res; |
return res; |
||
Line 529: | Line 1,003: | ||
immutable encoded = original.encrypt(key); |
immutable encoded = original.encrypt(key); |
||
writeln(encoded, "\n", encoded.decrypt(key)); |
writeln(encoded, "\n", encoded.decrypt(key)); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
<pre>WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
||
===Alternative Version=== |
|||
{{trans|Raku}} |
|||
<syntaxhighlight lang="d">import std.stdio, std.range, std.ascii, std.string, std.algorithm, |
|||
std.conv; |
|||
immutable mod = (in int m, in int n) pure nothrow @safe @nogc => |
|||
((m % n) + n) % n; |
|||
immutable _s2v = (in string s) pure /*nothrow*/ @safe => |
|||
s.toUpper.removechars("^A-Z").map!q{ a - 'A' }; |
|||
string _v2s(R)(R v) pure /*nothrow*/ @safe { |
|||
return v.map!(x => uppercase[x.mod(26)]).text; |
|||
} |
|||
immutable encrypt = (in string txt, in string key) pure /*nothrow*/ @safe => |
|||
txt._s2v.zip(key._s2v.cycle).map!q{ a[0] + a[1] }._v2s; |
|||
immutable decrypt = (in string txt, in string key) pure /*nothrow*/ @safe => |
|||
txt._s2v.zip(key._s2v.cycle).map!q{ a[0] - a[1] }._v2s; |
|||
void main() { |
|||
immutable key = "Vigenere Cipher!!!"; |
|||
immutable original = "Beware the Jabberwock, my son!" ~ |
|||
" The jaws that bite, the claws that catch!"; |
|||
immutable encoded = original.encrypt(key); |
|||
writeln(encoded, "\n", encoded.decrypt(key)); |
|||
}</syntaxhighlight> |
|||
The output is the same. |
|||
=={{header|Delphi}}== |
|||
{{works with|Delphi|6.0}} |
|||
{{libheader|SysUtils,StdCtrls}} |
|||
<syntaxhighlight lang="Delphi"> |
|||
function UpperAlphaOnly(S: string): string; |
|||
{Remove all } |
|||
var I: integer; |
|||
begin |
|||
Result:=''; |
|||
S:=UpperCase(S); |
|||
for I:=1 to Length(S) do |
|||
if S[I] in ['A'..'Z'] then Result:=Result+S[I]; |
|||
end; |
|||
function VigenereEncrypt(Text, Key: string): string; |
|||
{Encrypt Text using specified key} |
|||
var KInx,TInx,I: integer; |
|||
var TC: byte; |
|||
begin |
|||
Result:=''; |
|||
{Force Text and Key upper case} |
|||
Text:=UpperAlphaOnly(Text); |
|||
Key:=UpperAlphaOnly(Key); |
|||
{Point to first Key-character} |
|||
KInx:=1; |
|||
for I:=1 to Length(Text) do |
|||
begin |
|||
{Offset Text-char by key-char amount} |
|||
TC:=byte(Text[I])-byte('A')+Byte(Key[KInx]); |
|||
{if it is shifted past "Z", wrap back around past "A"} |
|||
if TC>Byte('Z') then TC:=byte('@')+(TC-Byte('Z')); |
|||
{Store in output string} |
|||
Result:=Result+Char(TC); |
|||
{Point to next Key-char} |
|||
Inc(Kinx); |
|||
{If index post end of key, start over} |
|||
if KInx>Length(Key) then KInx:=1; |
|||
end; |
|||
end; |
|||
function VigenereDecrypt(Text, Key: string): string; |
|||
{Encrypt Text using specified key} |
|||
var KInx,TInx,I: integer; |
|||
var TC: byte; |
|||
begin |
|||
Result:=''; |
|||
{For Key and text uppercase} |
|||
Text:=UpperAlphaOnly(Text); |
|||
Key:=UpperAlphaOnly(Key); |
|||
KInx:=1; |
|||
for I:=1 to Length(Text) do |
|||
begin |
|||
{subtrack key-char from text-char} |
|||
TC:=byte(Text[I])-Byte(Key[Kinx])+Byte('A'); |
|||
{if result below "A" wrap back around to "Z"} |
|||
if TC<Byte('A') then TC:=(byte('Z')-((Byte('A')-TC)))+1; |
|||
{store in result} |
|||
Result:=Result+Char(TC); |
|||
{Point to next key char} |
|||
Inc(Kinx); |
|||
{Past the end, start over} |
|||
if KInx>Length(Key) then KInx:=1; |
|||
end; |
|||
end; |
|||
const TestKey = 'VIGENERECIPHER'; |
|||
const TestStr = 'Beware the Jabberwock, my son! The jaws that bite, the claws that catch!'; |
|||
procedure VigenereCipher(Memo: TMemo); |
|||
var S: string; |
|||
begin |
|||
{Show plain text} |
|||
Memo.Lines.Add(TestStr); |
|||
S:=VigenereEncrypt(TestStr, TestKey); |
|||
{Show encrypted text} |
|||
Memo.Lines.Add(S); |
|||
S:=VigenereDecrypt(S, TestKey); |
|||
{Show decrypted text} |
|||
Memo.Lines.Add(S); |
|||
end; |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
Elapsed Time: 4.549 ms. |
|||
</pre> |
|||
=={{header|EasyLang}}== |
|||
<syntaxhighlight lang="easylang"> |
|||
func$ encr txt$ pw$ d . |
|||
txt$[] = strchars txt$ |
|||
for c$ in strchars pw$ |
|||
pw[] &= strcode c$ - 65 |
|||
. |
|||
for c$ in txt$[] |
|||
c = strcode c$ |
|||
if c >= 97 |
|||
c -= 32 |
|||
. |
|||
if c >= 65 and c <= 97 |
|||
pwi = (pwi + 1) mod1 len pw[] |
|||
c = (c - 65 + d * pw[pwi]) mod 26 + 65 |
|||
r$ &= strchar c |
|||
. |
|||
. |
|||
return r$ |
|||
. |
|||
s$ = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
pw$ = "VIGENERECIPHER" |
|||
r$ = encr s$ pw$ 1 |
|||
print r$ |
|||
print encr r$ pw$ -1 |
|||
</syntaxhighlight> |
|||
=={{header|Elena}}== |
|||
{{trans|C#}} |
|||
ELENA 6.x : |
|||
<syntaxhighlight lang="elena">import system'text; |
|||
import system'culture; |
|||
import system'math; |
|||
import system'routines; |
|||
import extensions; |
|||
class VCipher |
|||
{ |
|||
string encrypt(string txt, string pw, int d) |
|||
{ |
|||
auto output := new TextBuilder(); |
|||
int pwi := 0; |
|||
string PW := pw.toUpper(); |
|||
var TXT := txt.toUpper(); |
|||
foreach(char t; in TXT) |
|||
{ |
|||
if (t < $65) $continue; |
|||
int tmp := t - 65 + d * (pw[pwi] - 65); |
|||
if (tmp < 0) tmp += 26; |
|||
output.write((65 + tmp.mod(26)).toChar()); |
|||
pwi++; |
|||
if (pwi == PW.Length) { pwi := 0 } |
|||
}; |
|||
^ output.Value |
|||
} |
|||
} |
|||
public program() |
|||
{ |
|||
var v := new VCipher(); |
|||
var s0 := "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"; |
|||
var pw := "VIGENERECIPHER"; |
|||
console.printLine(s0,newLineConstant,pw,newLineConstant); |
|||
var s1 := v.encrypt(s0, pw, 1); |
|||
console.printLine("Encrypted:",s1); |
|||
s1 := v.encrypt(s1, "VIGENERECIPHER", -1); |
|||
console.printLine("Decrypted:",s1); |
|||
console.printLine("Press any key to continue.."); |
|||
console.readChar() |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
VIGENERECIPHER |
|||
Encrypted:WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
Decrypted:BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
Press any key to continue.. |
|||
</pre> |
|||
=={{header|Elixir}}== |
|||
{{trans|Ruby}} |
|||
<syntaxhighlight lang="elixir">defmodule VigenereCipher do |
|||
@base ?A |
|||
@size ?Z - @base + 1 |
|||
def encrypt(text, key), do: crypt(text, key, 1) |
|||
def decrypt(text, key), do: crypt(text, key, -1) |
|||
defp crypt(text, key, dir) do |
|||
text = String.upcase(text) |> String.replace(~r/[^A-Z]/, "") |> to_char_list |
|||
key_iterator = String.upcase(key) |> String.replace(~r/[^A-Z]/, "") |> to_char_list |
|||
|> Enum.map(fn c -> (c - @base) * dir end) |> Stream.cycle |
|||
Enum.zip(text, key_iterator) |
|||
|> Enum.reduce('', fn {char, offset}, ciphertext -> |
|||
[rem(char - @base + offset + @size, @size) + @base | ciphertext] |
|||
end) |
|||
|> Enum.reverse |> List.to_string |
|||
end |
|||
end |
|||
plaintext = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
key = "Vigenere cipher" |
|||
ciphertext = VigenereCipher.encrypt(plaintext, key) |
|||
recovered = VigenereCipher.decrypt(ciphertext, key) |
|||
IO.puts "Original: #{plaintext}" |
|||
IO.puts "Encrypted: #{ciphertext}" |
|||
IO.puts "Decrypted: #{recovered}"</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Original: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
</pre> |
|||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
Erlang is not ideal for string manipulation, but with some utility function definitions it can express this fairly elegantly: |
Erlang is not ideal for string manipulation, but with some utility function definitions it can express this fairly elegantly: |
||
< |
<syntaxhighlight lang="erlang">% Erlang implementation of Vigenère cipher |
||
-module(vigenere). |
-module(vigenere). |
||
-export([encrypt/2, decrypt/2]). |
-export([encrypt/2, decrypt/2]). |
||
Line 582: | Line 1,313: | ||
encrypt(Text, Key) -> crypt(Text, Key, fun encipher/2). |
encrypt(Text, Key) -> crypt(Text, Key, fun encipher/2). |
||
decrypt(Text, Key) -> crypt(Text, Key, fun decipher/2).</ |
decrypt(Text, Key) -> crypt(Text, Key, fun decipher/2).</syntaxhighlight> |
||
Demonstration code: |
Demonstration code: |
||
< |
<syntaxhighlight lang="erlang">-module(testvigenere). |
||
-import(vigenere,[encrypt/2, decrypt/2]). |
-import(vigenere,[encrypt/2, decrypt/2]). |
||
main(_) -> |
main(_) -> |
||
Line 591: | Line 1,322: | ||
CipherText = encrypt("Beware the Jabberwock, my son! The jaws that bite, the claws that catch!", Key), |
CipherText = encrypt("Beware the Jabberwock, my son! The jaws that bite, the claws that catch!", Key), |
||
RecoveredText = decrypt(CipherText, Key), |
RecoveredText = decrypt(CipherText, Key), |
||
io:fwrite("Ciphertext: ~s~nDecrypted: ~s~n", [CipherText, RecoveredText]).</ |
io:fwrite("Ciphertext: ~s~nDecrypted: ~s~n", [CipherText, RecoveredText]).</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre>Ciphertext: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
<pre>Ciphertext: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
< |
<syntaxhighlight lang="fsharp"> |
||
module vigenere = |
module vigenere = |
||
let keyschedule (key:string) = |
let keyschedule (key:string) = |
||
Line 626: | Line 1,357: | ||
let plain = vigenere.decrypt passwd cipher |
let plain = vigenere.decrypt passwd cipher |
||
printfn "%s\n%s" cipher plain |
printfn "%s\n%s" cipher plain |
||
</syntaxhighlight> |
|||
</lang> |
|||
<pre>C:\src\fsharp>fsi vigenere.fsx |
<pre>C:\src\fsharp>fsi vigenere.fsx |
||
Line 632: | Line 1,363: | ||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
||
</pre> |
</pre> |
||
=={{header|Factor}}== |
|||
<syntaxhighlight lang="text">USING: arrays ascii formatting kernel math math.functions |
|||
math.order sequences ; |
|||
IN: rosetta-code.vigenere-cipher |
|||
: mult-pad ( key input -- x ) |
|||
[ length ] bi@ 2dup < [ swap ] when / ceiling ; |
|||
: lengthen-pad ( key input -- rep-key input ) |
|||
[ mult-pad ] 2keep [ <repetition> concat ] dip |
|||
[ length ] keep [ head ] dip ; |
|||
: normalize ( str -- only-upper-letters ) |
|||
>upper [ LETTER? ] filter ; |
|||
: vigenere-encrypt ( key input -- ecrypted ) |
|||
[ normalize ] bi@ lengthen-pad |
|||
[ [ CHAR: A - ] map ] bi@ [ + 26 mod CHAR: A + ] 2map ; |
|||
: vigenere-decrypt ( key input -- decrypted ) |
|||
[ normalize ] bi@ lengthen-pad [ [ CHAR: A - ] map ] bi@ |
|||
[ - 26 - abs 26 mod CHAR: A + ] 2map ; |
|||
: main ( -- ) |
|||
"Vigenere cipher" dup |
|||
"Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
2dup "Key: %s\nInput: %s\n" printf |
|||
vigenere-encrypt dup "Encrypted: %s\n" printf |
|||
vigenere-decrypt "Decrypted: %s\n" printf ; |
|||
MAIN: main</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Key: Vigenere cipher |
|||
Input: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
</pre> |
|||
=={{header|Fortran}}== |
|||
{{works with|Fortran|95 and later}} |
|||
<syntaxhighlight lang="fortran">program vigenere_cipher |
|||
implicit none |
|||
character(80) :: plaintext = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!", & |
|||
ciphertext = "" |
|||
character(14) :: key = "VIGENERECIPHER" |
|||
call encrypt(plaintext, ciphertext, key) |
|||
write(*,*) plaintext |
|||
write(*,*) ciphertext |
|||
call decrypt(ciphertext, plaintext, key) |
|||
write(*,*) plaintext |
|||
contains |
|||
subroutine encrypt(intxt, outtxt, k) |
|||
character(*), intent(in) :: intxt, k |
|||
character(*), intent(out) :: outtxt |
|||
integer :: chrn |
|||
integer :: cp = 1, kp = 1 |
|||
integer :: i |
|||
outtxt = "" |
|||
do i = 1, len(trim(intxt)) |
|||
select case(intxt(i:i)) |
|||
case ("A":"Z", "a":"z") |
|||
select case(intxt(i:i)) |
|||
case("a":"z") |
|||
chrn = iachar(intxt(i:i)) - 32 |
|||
case default |
|||
chrn = iachar(intxt(i:i)) |
|||
end select |
|||
outtxt(cp:cp) = achar(modulo(chrn + iachar(k(kp:kp)), 26) + 65) |
|||
cp = cp + 1 |
|||
kp = kp + 1 |
|||
if(kp > len(k)) kp = kp - len(k) |
|||
end select |
|||
end do |
|||
end subroutine |
|||
subroutine decrypt(intxt, outtxt, k) |
|||
character(*), intent(in) :: intxt, k |
|||
character(*), intent(out) :: outtxt |
|||
integer :: chrn |
|||
integer :: cp = 1, kp = 1 |
|||
integer :: i |
|||
outtxt = "" |
|||
do i = 1, len(trim(intxt)) |
|||
chrn = iachar(intxt(i:i)) |
|||
outtxt(cp:cp) = achar(modulo(chrn - iachar(k(kp:kp)), 26) + 65) |
|||
cp = cp + 1 |
|||
kp = kp + 1 |
|||
if(kp > len(k)) kp = kp - len(k) |
|||
end do |
|||
end subroutine |
|||
end program</syntaxhighlight> |
|||
{{out}} |
|||
<pre> Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
|||
=={{header|FreeBASIC}}== |
|||
{{trans|Liberty BASIC}} |
|||
<syntaxhighlight lang="freebasic"> |
|||
Function Filtrar(cadorigen As String) As String |
|||
Dim As String letra |
|||
Dim As String filtrado = "" |
|||
For i As Integer = 1 To Len(cadorigen) |
|||
letra = Ucase(Mid(cadorigen, i, 1)) |
|||
If Instr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", letra) Then filtrado += letra |
|||
Next i |
|||
Return filtrado |
|||
End Function |
|||
Function Encriptar(texto As String, llave As String) As String |
|||
texto = Filtrar(texto) |
|||
Dim As String mSS, kSS, letra, cifrado = "" |
|||
Dim As Integer m, k, c, j = 1 |
|||
For i As Integer = 1 To Len(texto) |
|||
mSS = Mid(texto, i, 1) |
|||
m = Asc(mSS) - Asc("A") |
|||
kSS = Mid(llave, j, 1) |
|||
k = Asc(kSS) - Asc("A") |
|||
j = (j Mod Len(llave)) + 1 |
|||
c = (m + k) Mod 26 |
|||
letra = Chr(Asc("A") + c) |
|||
cifrado += letra |
|||
Next i |
|||
Return cifrado |
|||
End Function |
|||
Function DesEncriptar(texto As String, llave As String) As String |
|||
Dim As String mSS, kSS, letra, descifrado = "" |
|||
Dim As Integer m, k, c, j = 1 |
|||
For i As Integer = 1 To Len(texto) |
|||
mSS = Mid(texto, i, 1) |
|||
m = Asc(mSS) - Asc("A") |
|||
kSS = Mid(llave, j, 1) |
|||
k = Asc(kSS) - Asc("A") |
|||
j = (j Mod Len(llave)) + 1 |
|||
c = (m - k + 26) Mod 26 |
|||
letra = Chr(Asc("A")+c) |
|||
descifrado += letra |
|||
Next i |
|||
Return descifrado |
|||
End Function |
|||
Dim Shared As String llave |
|||
llave = Filtrar("vigenerecipher") |
|||
Dim As String cadorigen = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
Print cadorigen |
|||
Print llave |
|||
Dim As String cadcifrada = Encriptar(cadorigen, llave) |
|||
Print " Cifrado: "; cadcifrada |
|||
Print "Descifrado: "; DesEncriptar(cadcifrada, llave) |
|||
Sleep |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
VIGENERECIPHER |
|||
Cifrado: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
Descifrado: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
</pre> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import "fmt" |
import "fmt" |
||
Line 702: | Line 1,609: | ||
} |
} |
||
fmt.Println("Deciphered:", dt) |
fmt.Println("Deciphered:", dt) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
Supplied key: Vigenère Cipher |
Supplied key: Vigenère Cipher |
||
Line 714: | Line 1,621: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">import Data.Char |
||
import Text.Printf |
import Text.Printf |
||
Line 732: | Line 1,639: | ||
convert = map toUpper . filter isLetter |
convert = map toUpper . filter isLetter |
||
main :: IO () |
|||
main = do |
main = do |
||
let key = "VIGENERECIPHER" |
let key = "VIGENERECIPHER" |
||
Line 739: | Line 1,647: | ||
decr = decrypt key encr |
decr = decrypt key encr |
||
printf " Input: %s\n Key: %s\nEncrypted: %s\nDecrypted: %s\n" |
printf " Input: %s\n Key: %s\nEncrypted: %s\nDecrypted: %s\n" |
||
text key encr decr</ |
text key encr decr</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
Input: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
Input: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
||
Line 749: | Line 1,657: | ||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
< |
<syntaxhighlight lang="icon">procedure main() |
||
ptext := "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
ptext := "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
||
write("Key = ",ekey := "VIGENERECIPHER") |
write("Key = ",ekey := "VIGENERECIPHER") |
||
Line 772: | Line 1,680: | ||
} |
} |
||
return ctext |
return ctext |
||
end</ |
end</syntaxhighlight> |
||
The following helper procedures will be of general use with classical cryptography tasks. |
The following helper procedures will be of general use with classical cryptography tasks. |
||
<syntaxhighlight lang="icon"> |
|||
<lang Icon> |
|||
link strings |
link strings |
||
Line 788: | Line 1,696: | ||
text ? (s := "", until pos(0) do s ||:= " " || move(5)|tab(0)) |
text ? (s := "", until pos(0) do s ||:= " " || move(5)|tab(0)) |
||
return s[2:0] |
return s[2:0] |
||
end</ |
end</syntaxhighlight> |
||
{{libheader|Icon Programming Library}} |
{{libheader|Icon Programming Library}} |
||
[http://www.cs.arizona.edu/icon/library/src/procs/strings.icn strings.icn provides deletec] |
[http://www.cs.arizona.edu/icon/library/src/procs/strings.icn strings.icn provides deletec] |
||
{{out}} |
|||
Output:<pre>Key = VIGENERECIPHER |
|||
<pre>Key = VIGENERECIPHER |
|||
Plain Text = Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
Plain Text = Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
||
Normalized = BEWAR ETHEJ ABBER WOCKM YSONT HEJAW STHAT BITET HECLA WSTHA TCATCH |
Normalized = BEWAR ETHEJ ABBER WOCKM YSONT HEJAW STHAT BITET HECLA WSTHA TCATCH |
||
Line 801: | Line 1,710: | ||
=={{header|J}}== |
=={{header|J}}== |
||
'''Solution:'''<br> |
'''Solution:'''<br> |
||
Using <code>vig</code> from the [[j:Addons/convert/misc/vig|convert/misc/vig addon]]: |
Using [https://github.com/jsoftware/convert_misc/blob/master/vig.ijs <code>vig</code>] from the [[j:Addons/convert/misc/vig|convert/misc/vig addon]]: |
||
<syntaxhighlight lang="j">ALPHA=: (65,:26) ];.0 a. NB. Character Set |
|||
<lang j>NB.*vig c Vigenère cipher |
|||
NB. cipher=. key 0 vig charset plain |
|||
NB. plain=. key 1 vig charset cipher |
|||
vig=: conjunction define |
|||
: |
|||
r=. (#y) $ n i.x |
|||
n {~ (#n) | (r*_1^m) + n i.y |
|||
) |
|||
ALPHA=: (65,:26) ];.0 a. NB. Character Set |
|||
preprocess=: (#~ e.&ALPHA)@toupper NB. force uppercase and discard non-alpha chars |
preprocess=: (#~ e.&ALPHA)@toupper NB. force uppercase and discard non-alpha chars |
||
vigEncryptRC=: 0 vig ALPHA preprocess |
vigEncryptRC=: 0 vig ALPHA preprocess |
||
vigDecryptRC=: 1 vig ALPHA preprocess</ |
vigDecryptRC=: 1 vig ALPHA preprocess</syntaxhighlight> |
||
'''Example Use:''' |
'''Example Use:''' |
||
< |
<syntaxhighlight lang="j"> 'VIGENERECIPHER' vigEncryptRC 'Beware the Jabberwock, my son! The jaws that bite, the claws that catch!' |
||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
'VIGENERECIPHER' vigDecryptRC 'WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY' |
'VIGENERECIPHER' vigDecryptRC 'WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY' |
||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</ |
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
{{trans|D}} |
{{trans|D}} |
||
< |
<syntaxhighlight lang="java">public class VigenereCipher { |
||
public static void main(String[] args) { |
public static void main(String[] args) { |
||
String key = "VIGENERECIPHER"; |
String key = "VIGENERECIPHER"; |
||
Line 857: | Line 1,756: | ||
return res; |
return res; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
<pre>WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
<pre>WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
||
===Alternative Version=== |
|||
<syntaxhighlight lang="java"> |
|||
import com.google.common.collect.Streams; |
|||
import java.util.function.Supplier; |
|||
import java.util.stream.Collectors; |
|||
import java.util.stream.Stream; |
|||
import static java.nio.charset.StandardCharsets.US_ASCII; |
|||
public class VigenereCipher { |
|||
private final static int LOWER = 'A'; |
|||
private final static int UPPER = 'Z'; |
|||
private final static int SIZE = UPPER - LOWER + 1; |
|||
private final Supplier<Stream<Character>> maskStream; |
|||
public VigenereCipher(final String key) { |
|||
final String mask = new String(key.getBytes(US_ASCII)).toUpperCase(); |
|||
maskStream = () -> |
|||
Stream.iterate(0, i -> (i+1) % mask.length()).map(mask::charAt); |
|||
} |
|||
private String transform(final String text, final boolean encode) { |
|||
final Stream<Integer> textStream = text.toUpperCase().chars().boxed() |
|||
.filter(i -> i >= LOWER && i <= UPPER); |
|||
return Streams.zip(textStream, maskStream.get(), (c, m) -> |
|||
encode ? c + m - 2 * LOWER : c - m + SIZE) |
|||
.map(c -> Character.toString(c % SIZE + LOWER)) |
|||
.collect(Collectors.joining()); |
|||
} |
|||
public String encrypt(final String plaintext) { |
|||
return transform(plaintext,true); |
|||
} |
|||
public String decrypt(final String ciphertext) { |
|||
return transform(ciphertext,false); |
|||
} |
|||
} |
|||
import org.junit.jupiter.api.DisplayName; |
|||
import org.junit.jupiter.api.Test; |
|||
import static org.junit.jupiter.api.Assertions.assertEquals; |
|||
class VigenereCipherTest { |
|||
private static final VigenereCipher Vigenere = new VigenereCipher("VIGENERECIPHER"); |
|||
@Test |
|||
@DisplayName("encipher/decipher round-trip succeeds") |
|||
void vigenereCipherTest() { |
|||
final String input = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"; |
|||
final String expectEncrypted = "WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY"; |
|||
final String expectDecrypted = "BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH"; |
|||
final String ciphertext = Vigenere.encrypt(input); |
|||
assertEquals(expectEncrypted, ciphertext); |
|||
final String plaintext = Vigenere.decrypt(ciphertext); |
|||
assertEquals(expectDecrypted, plaintext); |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
<lang |
<syntaxhighlight lang="javascript">// helpers |
||
// helper |
|||
<body><pre id='x'></pre> |
|||
function ordA(a) { |
|||
<script type="application/javascript"> |
|||
return a.charCodeAt(0) - 65; |
|||
function disp(x) { |
|||
var e = document.createTextNode(x + '\n'); |
|||
document.getElementById('x').appendChild(e); |
|||
} |
} |
||
// vigenere |
|||
function ord(x) { return x.charCodeAt(0) } |
|||
function |
function vigenere(text, key, decode) { |
||
var i = 0, b; |
|||
function rot(a, b, decode) { |
|||
key = key.toUpperCase().replace(/[^A-Z]/g, ''); |
|||
return decode ? chr((26 + ord(a) - ord(b)) % 26 + ord('A')) |
|||
return text.toUpperCase().replace(/[^A-Z]/g, '').replace(/[A-Z]/g, function(a) { |
|||
: chr((26 + ord(a) + ord(b) - ord('A') * 2) % 26 + ord('A')) } |
|||
b = key[i++ % key.length]; |
|||
return String.fromCharCode(((ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26 + 65)); |
|||
}); |
|||
} |
|||
// example |
|||
function trans(msg, key, decode) { |
|||
var text = "The quick brown fox Jumped over the lazy Dog the lazy dog lazy dog dog"; |
|||
var i = 0; |
|||
var key = 'alex'; |
|||
var enc = vigenere(text,key); |
|||
msg = msg.toUpperCase().replace(/[^A-Z]/g, ''); |
|||
var dec = vigenere(enc,key,true); |
|||
return msg.replace(/([A-Z])/g, |
|||
function($1) { return rot($1, key[i++ % key.length], decode) }); |
|||
console.log(enc); |
|||
console.log(dec);</syntaxhighlight> |
|||
=={{header|jq}}== |
|||
{{works with|jq}} |
|||
'''Works with gojq, the Go implementation of jq''' |
|||
<syntaxhighlight lang="jq">def vigenere(text; key; encryptp): |
|||
# retain alphabetic characters only |
|||
def n: |
|||
ascii_upcase | explode | map(select(65 <= . and . <= 90)) | [., length]; |
|||
(text | n) as [$xtext, $length] |
|||
| (key | n) as [$xkey, $keylength] |
|||
| reduce range(0; $length) as $i (null; |
|||
($i % $keylength) as $ki |
|||
| . + [if encryptp |
|||
then (($xtext[$i] + $xkey[$ki] - 130) % 26) + 65 |
|||
else (($xtext[$i] - $xkey[$ki] + 26) % 26) + 65 |
|||
end] ) |
|||
| implode; |
|||
# Input: sample text |
|||
def example($key): |
|||
vigenere(.; $key; true) |
|||
| . as $encoded |
|||
| ., vigenere($encoded; $key; false) ; |
|||
"Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
| (., example("VIGENERECIPHER")), |
|||
"", |
|||
(., example("ROSETTACODE"))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
SSOEKXTJSMESPWVPHCMABWFBLLXCAYGWLRHTMMXTJSFPRKKXATTEOWGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
|||
=={{header|Jsish}}== |
|||
From Javascript entry. |
|||
<syntaxhighlight lang="javascript">/* Vigenère cipher, in Jsish */ |
|||
"use strict"; |
|||
function ordA(a:string):number { |
|||
return a.charCodeAt(0) - 65; |
|||
} |
} |
||
// vigenere |
|||
function vigenereCipher(text:string, key:string, decode:boolean=false):string { |
|||
var i = 0, b; |
|||
key = key.toUpperCase().replace(/[^A-Z]/g, ''); |
|||
return text.toUpperCase().replace(/[^A-Z]/g, '').replace(/[A-Z]/g, |
|||
function(a:string, idx:number, str:string) { |
|||
b = key[i++ % key.length]; |
|||
return String.fromCharCode(((ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26 + 65)); |
|||
}); |
|||
} |
|||
provide('vigenereCipher', 1); |
|||
if (Interp.conf('unitTest')) { |
|||
var text = "The quick brown fox Jumped over the lazy Dog the lazy dog lazy dog dog"; |
|||
var key = 'jsish'; |
|||
var enc = vigenereCipher(text, key); |
|||
; text; |
|||
; enc; |
|||
; vigenereCipher(enc, key, true); |
|||
} |
|||
/* |
|||
=!EXPECTSTART!= |
|||
text ==> The quick brown fox Jumped over the lazy Dog the lazy dog lazy dog dog |
|||
enc ==> CZMIBRUSTYXOVXVGBCEWNVWNLALPWSJRGVVPLPWSJRGVVPDIRFMGOVVP |
|||
vigenere(enc, key, true) ==> THEQUICKBROWNFOXJUMPEDOVERTHELAZYDOGTHELAZYDOGLAZYDOGDOG |
|||
=!EXPECTEND!= |
|||
*/</syntaxhighlight> |
|||
{{out}} |
|||
<pre>prompt$ jsish -u vigenereCipher.jsi |
|||
[PASS] vigenereCipher.jsi</pre> |
|||
=={{header|Julia}}== |
|||
{{works with|Julia|1.5}} |
|||
<syntaxhighlight lang="julia"> |
|||
→(a::Char, b::Char, ± = +) = 'A'+((a-'A')±(b-'A')+26)%26 |
|||
←(a::Char, b::Char) = →(a,b,-) |
|||
cleanup(str) = filter(a-> a in 'A':'Z', collect(uppercase.(str))) |
|||
match_length(word, len) = repeat(word,len)[1:len] |
|||
function →(message::String, codeword::String, ↔ = →) |
|||
plaintext = cleanup(message) |
|||
key = match_length(cleanup(codeword),length(plaintext)) |
|||
return String(plaintext .↔ key) |
|||
end |
|||
←(message::String, codeword::String) = →(message,codeword,←) |
|||
cyphertext = "I want spearmint gum" → "Gimme!" |
|||
println(cyphertext) |
|||
println(cyphertext ← "Gimme!") |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
"OEMZXYXQMVSQZFKAU" |
|||
"IWANTSPEARMINTGUM" |
|||
</pre> |
|||
=={{header|Kotlin}}== |
|||
<syntaxhighlight lang="scala">// version 1.1.3 |
|||
fun vigenere(text: String, key: String, encrypt: Boolean = true): String { |
|||
val t = if (encrypt) text.toUpperCase() else text |
|||
val sb = StringBuilder() |
|||
var ki = 0 |
|||
for (c in t) { |
|||
if (c !in 'A'..'Z') continue |
|||
val ci = if (encrypt) |
|||
(c.toInt() + key[ki].toInt() - 130) % 26 |
|||
else |
|||
(c.toInt() - key[ki].toInt() + 26) % 26 |
|||
sb.append((ci + 65).toChar()) |
|||
ki = (ki + 1) % key.length |
|||
} |
|||
return sb.toString() |
|||
} |
|||
fun main(args: Array<String>) { |
|||
val key = "VIGENERECIPHER" |
|||
val text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
val encoded = vigenere(text, key) |
|||
println(encoded) |
|||
val decoded = vigenere(encoded, key, false) |
|||
println(decoded) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
</pre> |
|||
=={{header|Lambdatalk}}== |
|||
Only texts in uppercases [A-Z] and spaces. |
|||
<syntaxhighlight lang="scheme"> |
|||
{def vigenere |
|||
{def vigenere.map |
|||
{lambda {:code :key :txt} |
|||
{S.map |
|||
{{lambda {:code :txt :key :i} |
|||
{W.code2char |
|||
{+ {% {+ {W.char2code {W.get :i :txt}} |
|||
{if :code |
|||
then {W.char2code {W.get {% :i {W.length :key}} :key}} |
|||
else {- 26 {W.char2code {W.get {% :i {W.length :key}} :key}}} }} |
|||
26} |
|||
65}} } :code :txt :key} |
|||
{S.serie 0 {- {W.length :txt} 1}}} }} |
|||
{lambda {:code :key :txt} |
|||
{S.replace \s by in {vigenere.map :code :key {S.replace \s by in :txt}}} }} |
|||
-> vigenere |
|||
1) encode: {vigenere true LEMON ATTACK AT DAWN} |
|||
-> LXFOPVEFRNHR |
|||
2) decode: {vigenere false LEMON LXFOPVEFRNHR} |
|||
var msg = "The quick brown fox Jumped over the lazy Dog the lazy dog lazy dog dog"; |
|||
-> ATTACKATDAWN |
|||
var key = 'VIGENERECIPHER'; |
|||
var enc = trans(msg, key); |
|||
var dec = trans(enc, key, 'decipher'); |
|||
</syntaxhighlight> |
|||
disp("Original:" + msg + "\nEncoded: " + enc + "\nDecoded: " + dec); |
|||
</script></body></html></lang> |
|||
=={{header|Liberty BASIC}}== |
=={{header|Liberty BASIC}}== |
||
<syntaxhighlight lang="lb"> |
|||
<lang lb> |
|||
ori$ = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
ori$ = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
||
key$ = filter$("vigenerecipher") |
key$ = filter$("vigenerecipher") |
||
Line 945: | Line 2,071: | ||
next |
next |
||
end function |
end function |
||
</syntaxhighlight> |
|||
</lang> |
|||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
||
VIGENERECIPHER |
VIGENERECIPHER |
||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<syntaxhighlight lang="lua">function Encrypt( _msg, _key ) |
||
local msg = { _msg:upper():byte( 1, -1 ) } |
local msg = { _msg:upper():byte( 1, -1 ) } |
||
local key = { _key:upper():byte( 1, -1 ) } |
local key = { _key:upper():byte( 1, -1 ) } |
||
Line 996: | Line 2,120: | ||
print( encrypted ) |
print( encrypted ) |
||
print( decrypted )</ |
print( decrypted )</syntaxhighlight> |
||
<pre>WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
<pre>WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
||
=={{header|Mathematica}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">encode[text_String, key_String] := |
||
Module[{textCode, keyCode}, |
Module[{textCode, keyCode}, |
||
textCode = |
textCode = |
||
Line 1,031: | Line 2,155: | ||
keyCode[[;; Length@textCode]], |
keyCode[[;; Length@textCode]], |
||
PadRight[keyCode, Length@textCode, keyCode]]; |
PadRight[keyCode, Length@textCode, keyCode]]; |
||
FromCharacterCode[Mod[textCode - keyCode, 26] + 65]]</ |
FromCharacterCode[Mod[textCode - keyCode, 26] + 65]]</syntaxhighlight> |
||
<pre>key = "Vigenere Cipher"; |
<pre>key = "Vigenere Cipher"; |
||
Line 1,047: | Line 2,171: | ||
=={{header|NetRexx}}== |
=={{header|NetRexx}}== |
||
< |
<syntaxhighlight lang="netrexx">/* NetRexx */ |
||
options replace format comments java crossref savelog symbols nobinary |
options replace format comments java crossref savelog symbols nobinary |
||
Line 1,199: | Line 2,323: | ||
return melancholy_dane |
return melancholy_dane |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
|||
;Output |
|||
<pre style="height: 60ex; overflow:scroll"> |
<pre style="height: 60ex; overflow:scroll"> |
||
....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| |
....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| |
||
Line 1,271: | Line 2,395: | ||
EALLM YSINS REMEM BERED |
EALLM YSINS REMEM BERED |
||
</pre> |
</pre> |
||
=={{header|Nim}}== |
|||
<syntaxhighlight lang="nim">import strutils |
|||
proc encrypt(msg, key: string): string = |
|||
var pos = 0 |
|||
for c in msg: |
|||
if c in Letters: |
|||
result.add chr(((ord(key[pos]) + ord(c.toUpperAscii)) mod 26) + ord('A')) |
|||
pos = (pos + 1) mod key.len |
|||
proc decrypt(msg, key: string): string = |
|||
var pos = 0 |
|||
for c in msg: |
|||
result.add chr(((26 + ord(c) - ord(key[pos])) mod 26) + ord('A')) |
|||
pos = (pos + 1) mod key.len |
|||
const text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
const key = "VIGENERECIPHER" |
|||
let encr = encrypt(text, key) |
|||
let decr = decrypt(encr, key) |
|||
echo text |
|||
echo encr |
|||
echo decr</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
|||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
{{trans|D}} |
{{trans|D}} |
||
< |
<syntaxhighlight lang="objeck"> |
||
bundle Default { |
bundle Default { |
||
class VigenereCipher { |
class VigenereCipher { |
||
Line 1,320: | Line 2,475: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
<pre> |
<pre> |
||
encrypt: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
encrypt: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
Line 1,329: | Line 2,484: | ||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="ocaml">let cipher src key crypt = |
||
let str = String.uppercase src in |
let str = String.uppercase src in |
||
let key = String.uppercase key in |
let key = String.uppercase key in |
||
Line 1,369: | Line 2,524: | ||
Printf.printf "Code: %s\n" cod; |
Printf.printf "Code: %s\n" cod; |
||
Printf.printf "Back: %s\n" dec; |
Printf.printf "Back: %s\n" dec; |
||
;;</ |
;;</syntaxhighlight> |
||
Run: |
Run: |
||
Line 1,378: | Line 2,533: | ||
Code: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
Code: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
Back: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
Back: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
||
---- |
|||
Updated version by [http://rosettacode.org/wiki/User:Vanyamil User:Vanyamil] |
|||
This is a custom, more functional version of the existing solution, due to |
|||
'''[https://ocaml.org/api/String.html OCaml 4.05's unsafe-string compatibility mode]''' |
|||
{{works with|OCaml|4.05 or above}} |
|||
<syntaxhighlight lang="ocaml"> |
|||
(* Task : Vigenère_cipher *) |
|||
(* This is a custom, more functional version of an existing solution, |
|||
due to OCaml 4.05's unsafe-string compatibility mode: |
|||
https://ocaml.org/api/String.html |
|||
*) |
|||
(*** Helpers ***) |
|||
(* Verbose type abbreviation *) |
|||
type key = string |
|||
(* Rotate a single uppercase letter *) |
|||
let ascii_caesar_shift : bool -> char -> char -> char = |
|||
let min_range = Char.code 'A' in |
|||
let max_range = Char.code 'Z' in |
|||
(* aka 26 but this code can be adapted to larger ranges, such as the ASCII printable range (codes 32 to 126). *) |
|||
let range_len = max_range - min_range + 1 in |
|||
let actual_fun (dir : bool) (c1 : char) (c2 : char) : char = |
|||
let n1 = Char.code c1 in |
|||
let n2 = Char.code c2 - min_range in |
|||
let sum = (if dir then (+) else (-)) n1 n2 in |
|||
( (* Effectively mod function, but simplified and works on negatives. *) |
|||
if sum > max_range |
|||
then sum - range_len |
|||
else if sum < min_range |
|||
then sum + range_len |
|||
else sum |
|||
) |> Char.chr |
|||
in |
|||
actual_fun |
|||
(* Remove non-letters and uppercase *) |
|||
let ascii_upper_letters_only (s : string) : string = |
|||
let slen = String.length s in |
|||
(* Make a list of escaped uppercase letter chars *) |
|||
let rec toLetterList sidx acc = |
|||
if sidx >= slen |
|||
then List.rev acc |
|||
else |
|||
let c = s.[sidx] in |
|||
if c >= 'A' && c <= 'Z' |
|||
then toLetterList (sidx + 1) ((c |> Char.escaped) :: acc) |
|||
else if c >= 'a' && c <= 'z' |
|||
then toLetterList (sidx + 1) ((c |> Char.uppercase_ascii |> Char.escaped) :: acc) |
|||
else toLetterList (sidx + 1) acc |
|||
in |
|||
toLetterList 0 [] |> String.concat "" |
|||
(*** Actual task at hand ***) |
|||
let vig_crypt (dir : bool) (key : key) (message : string) : string = |
|||
let message = ascii_upper_letters_only message in |
|||
let key = ascii_upper_letters_only key in |
|||
let klen = String.length key in |
|||
let aux idx c = |
|||
let kidx = idx mod klen in |
|||
let e = ascii_caesar_shift dir c key.[kidx] in |
|||
e |
|||
in |
|||
String.mapi aux message |
|||
let encrypt : key -> string -> string = vig_crypt true |
|||
let decrypt : key -> string -> string = vig_crypt false |
|||
(*** Output ***) |
|||
let () = |
|||
let str = "Beware the Jabberwock, my son! The jaws that bite, \ |
|||
the claws that catch!" in |
|||
let key = "VIGENERECIPHER" in |
|||
let ct = encrypt key str in |
|||
let pt = decrypt key ct in |
|||
Printf.printf "Text: %s\n" str; |
|||
Printf.printf "Key: %s\n" key; |
|||
Printf.printf "Code: %s\n" ct; |
|||
Printf.printf "Back: %s\n" pt |
|||
;; |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
Key: VIGENERECIPHER |
|||
Code: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
Back: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
</pre> |
|||
=={{header|ooRexx}}== |
=={{header|ooRexx}}== |
||
{{trans|NetRexx}} |
{{trans|NetRexx}} |
||
A reworking of the [[#NetRexx|NetRexx]] version using Open Object Rexx but shouldn't take much to translate to Classic Rexx. |
A reworking of the [[#NetRexx|NetRexx]] version using Open Object Rexx but shouldn't take much to translate to Classic Rexx. |
||
< |
<syntaxhighlight lang="rexx">/* Rexx */ |
||
Do |
Do |
||
alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
||
Line 1,576: | Line 2,827: | ||
End |
End |
||
Exit |
Exit |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
|||
;Output |
|||
<pre style="height: 60ex; overflow: scroll;"> |
<pre style="height: 60ex; overflow: scroll;"> |
||
....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| |
....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| |
||
Line 1,647: | Line 2,898: | ||
OSETH ENAME OFACT IONSO FTYOU NOWTH EFAIR OPHEL IANYM PHINT HYORI SONSB |
OSETH ENAME OFACT IONSO FTYOU NOWTH EFAIR OPHEL IANYM PHINT HYORI SONSB |
||
EALLM YSINS REMEM BERED |
EALLM YSINS REMEM BERED |
||
</pre> |
|||
=={{header|Pascal}}== |
|||
<syntaxhighlight lang="pascal"> |
|||
// The Vigenere cipher in reasonably standard Pascal |
|||
// <no library functions: all conversions hand-coded> |
|||
PROGRAM Vigenere; |
|||
// get a letter's alphabetic position (A=0) |
|||
FUNCTION letternum(letter: CHAR): BYTE; |
|||
BEGIN |
|||
letternum := (ord(letter)-ord('A')); |
|||
END; |
|||
// convert a character to uppercase |
|||
FUNCTION uch(ch: CHAR): CHAR; |
|||
BEGIN |
|||
uch := ch; |
|||
IF ch IN ['a'..'z'] THEN |
|||
uch := chr(ord(ch) AND $5F); |
|||
END; |
|||
// convert a string to uppercase |
|||
FUNCTION ucase(str: STRING): STRING; |
|||
VAR i: BYTE; |
|||
BEGIN |
|||
ucase := ''; |
|||
FOR i := 1 TO Length(str) DO |
|||
ucase := ucase + uch(str[i]); |
|||
END; |
|||
// construct a Vigenere-compatible string: |
|||
// uppercase; no spaces or punctuation. |
|||
FUNCTION vstr(pt: STRING): STRING; |
|||
VAR c: Cardinal; |
|||
s: STRING; |
|||
BEGIN |
|||
vstr:= ''; |
|||
s := ucase(pt); |
|||
FOR c := 1 TO Length(s) DO BEGIN |
|||
IF s[c] IN ['A'..'Z'] THEN |
|||
vstr += s[c]; |
|||
END; |
|||
END; |
|||
// construct a repeating Vigenere key |
|||
FUNCTION vkey(pt, key: STRING): STRING; |
|||
VAR c,n: Cardinal; |
|||
k : STRING; |
|||
BEGIN |
|||
k := vstr(key); |
|||
vkey := ''; |
|||
FOR c := 1 TO Length(pt) DO BEGIN |
|||
n := c mod Length(k); |
|||
IF n>0 THEN vkey += k[n] ELSE vkey += k[Length(k)]; |
|||
END; |
|||
END; |
|||
// Vigenere encipher |
|||
FUNCTION enVig(pt,key:STRING): STRING; |
|||
VAR ct: STRING; |
|||
c,n : Cardinal; |
|||
BEGIN |
|||
ct := pt; |
|||
FOR c := 1 TO Length(pt) DO BEGIN |
|||
n := letternum(pt[c])+letternum(key[c]); |
|||
n := n mod 26; |
|||
ct[c]:=chr(ord('A')+n); |
|||
END; |
|||
enVig := ct; |
|||
END; |
|||
// Vigenere decipher |
|||
FUNCTION deVig(ct,key:STRING): STRING; |
|||
VAR pt : STRING; |
|||
c,n : INTEGER; |
|||
BEGIN |
|||
pt := ct; |
|||
FOR c := 1 TO Length(ct) DO BEGIN |
|||
n := letternum(ct[c])-letternum(key[c]); |
|||
IF n<0 THEN n:=26+n; |
|||
pt[c]:=chr(ord('A')+n); |
|||
END; |
|||
deVig := pt; |
|||
END; |
|||
VAR key: STRING = 'Vigenere cipher'; |
|||
msg: STRING = 'Beware the Jabberwock! The jaws that bite, the claws that catch!'; |
|||
vtx: STRING = ''; |
|||
ctx: STRING = ''; |
|||
ptx: STRING = ''; |
|||
BEGIN |
|||
// make Vigenere-compatible |
|||
vtx := vstr(msg); |
|||
key := vkey(vtx,key); |
|||
// Vigenere encipher / decipher |
|||
ctx := enVig(vtx,key); |
|||
ptx := deVig(ctx,key); |
|||
// display results |
|||
Writeln('Message : ',msg); |
|||
Writeln('Plaintext : ',vtx); |
|||
Writeln('Key : ',key); |
|||
Writeln('Ciphertext : ',ctx); |
|||
Writeln('Plaintext : ',ptx); |
|||
END. |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Message : Beware the Jabberwock! The jaws that bite, the claws that catch! |
|||
Plaintext : BEWARETHEJABBERWOCKTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
Key : VIGENERECIPHERVIGENERECIPHERVIGENERECIPHERVIGENEREC |
|||
Ciphertext : WMCEEIKLGRPIFVMEUGXXYILILZXYVBHMGIKLGKAHAJOPGXPEKGJ |
|||
Plaintext : BEWARETHEJABBERWOCKTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
</pre> |
</pre> |
||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang="perl">if( @ARGV != 3 ){ |
||
printHelp(); |
printHelp(); |
||
} |
} |
||
Line 1,667: | Line 3,035: | ||
if( $cipher_decipher =~ /ENC/ ){ |
if( $cipher_decipher =~ /ENC/ ){ |
||
print "Plain-text: " . (my $plain = $ARGV[ 1 ]) . "\n"; |
print "Plain-text: " . (my $plain = $ARGV[ 1 ]) . "\n"; |
||
print "Encrypted: " . Vigenere( 1, $plain ) . "\n"; |
print "Encrypted: " . Vigenere( 1, $key, $plain ) . "\n"; |
||
}elsif( $cipher_decipher =~ /DEC/ ){ |
}elsif( $cipher_decipher =~ /DEC/ ){ |
||
print "Cipher-text: " . (my $cipher = $ARGV[ 1 ]) . "\n"; |
print "Cipher-text: " . (my $cipher = $ARGV[ 1 ]) . "\n"; |
||
print "Decrypted: " . Vigenere( -1, $cipher ) . "\n"; |
print "Decrypted: " . Vigenere( -1, $key, $cipher ) . "\n"; |
||
} |
} |
||
Line 1,681: | Line 3,049: | ||
sub Vigenere{ |
sub Vigenere{ |
||
my ($direction, $text) = @_; |
my ($direction, $key, $text) = @_; |
||
for( my $count = 0; $count < length $text; $count ++ ){ |
for( my $count = 0; $count < length $text; $count ++ ){ |
||
$key_offset = $direction * ord substr( $key, $count % length $key, 1); |
$key_offset = $direction * ord substr( $key, $count % length $key, 1); |
||
Line 1,689: | Line 3,057: | ||
} |
} |
||
return $cipher; |
return $cipher; |
||
}</ |
}</syntaxhighlight> |
||
Demonstration: |
Demonstration: |
||
Line 1,710: | Line 3,078: | ||
perl cipher.pl DEC (cipher text) (key)</pre> |
perl cipher.pl DEC (cipher text) (key)</pre> |
||
=={{header| |
=={{header|Phix}}== |
||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<lang perl6>sub s2v ($s) { $s.uc.comb(/ <[ A..Z ]> /)».ord »-» 65 } |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
sub v2s (@v) { (@v »%» 26 »+» 65)».chr.join } |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">ENCRYPT</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">DECRYPT</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">Vigenere</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">key</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">mode</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ch</span> |
|||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'A'</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;"><=</span><span style="color: #008000;">'Z'</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'A'</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">+</span><span style="color: #000000;">mode</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">key</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">26</span><span style="color: #0000FF;">),</span><span style="color: #000000;">26</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">key</span><span style="color: #0000FF;">))+</span><span style="color: #000000;">1</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">key</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"LEMON"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"ATTACK AT DAWN"</span><span style="color: #0000FF;">,</span> |
|||
<span style="color: #000000;">e</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">Vigenere</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">key</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ENCRYPT</span><span style="color: #0000FF;">),</span> |
|||
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">Vigenere</span><span style="color: #0000FF;">(</span><span style="color: #000000;">e</span><span style="color: #0000FF;">,</span><span style="color: #000000;">key</span><span style="color: #0000FF;">,</span><span style="color: #000000;">DECRYPT</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Original: %s\nEncrypted: %s\nDecrypted: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">})</span> |
|||
<!--</syntaxhighlight>--> |
|||
{{Out}} |
|||
<pre> |
|||
Original: ATTACK AT DAWN |
|||
Encrypted: LXFOPVEFRNHR |
|||
Decrypted: ATTACKATDAWN |
|||
</pre> |
|||
=={{header|PHP}}== |
|||
sub blacken ($red, $key) { v2s s2v($red) »+» s2v($key) } |
|||
{{trans|C}} |
|||
sub redden ($blk, $key) { v2s s2v($blk) »-» s2v($key) } |
|||
<syntaxhighlight lang="php"><?php |
|||
$str = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"; |
|||
$key = "VIGENERECIPHER"; |
|||
printf("Text: %s\n", $str); |
|||
say $red; |
|||
printf("key: %s\n", $key); |
|||
say redden($black, $key);</lang> |
|||
$cod = encipher($str, $key, true); printf("Code: %s\n", $cod); |
|||
Output: |
|||
$dec = encipher($cod, $key, false); printf("Back: %s\n", $dec); |
|||
<pre>Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
function encipher($src, $key, $is_encode) |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
|||
{ |
|||
This is a natural job for hyperoperators, which can vectorize any operator. |
|||
$key = strtoupper($key); |
|||
For infix operators the pointy end indicates which side to "dwim", repeating |
|||
$src = strtoupper($src); |
|||
elements on that side until the other side runs out. In particular, repeating |
|||
$dest = ''; |
|||
the key naturally falls out of this cyclic dwimmery, as does repeating the various constants to be applied with any of several operations to every element of the list. Factoring out the canonicalization and decanonicalization lets us see quite clearly that the only difference between encryption and decryptions is the sign of the vector addition/subtraction. Since hyperops are inherently parallelizable, this algorithm might run well in your GPU. |
|||
/* strip out non-letters */ |
|||
for($i = 0; $i <= strlen($src); $i++) { |
|||
$char = substr($src, $i, 1); |
|||
if(ctype_upper($char)) { |
|||
$dest .= $char; |
|||
} |
|||
} |
|||
for($i = 0; $i <= strlen($dest); $i++) { |
|||
$char = substr($dest, $i, 1); |
|||
if(!ctype_upper($char)) { |
|||
continue; |
|||
} |
|||
$dest = substr_replace($dest, |
|||
chr ( |
|||
ord('A') + |
|||
($is_encode |
|||
? ord($char) - ord('A') + ord($key[$i % strlen($key)]) - ord('A') |
|||
: ord($char) - ord($key[$i % strlen($key)]) + 26 |
|||
) % 26 |
|||
) |
|||
, $i, 1); |
|||
} |
|||
return $dest; |
|||
} |
|||
?> |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
key: VIGENERECIPHER |
|||
Code: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
Back: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
|||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">(de vigenereKey (Str) |
||
(extract |
(extract |
||
'((C) |
'((C) |
||
Line 1,754: | Line 3,188: | ||
(char (+ 65 (% (+ 26 (- C K)) 26))) ) |
(char (+ 65 (% (+ 26 (- C K)) 26))) ) |
||
(vigenereKey Str) |
(vigenereKey Str) |
||
(apply circ (vigenereKey Key)) ) ) )</ |
(apply circ (vigenereKey Key)) ) ) )</syntaxhighlight> |
||
Test: |
Test: |
||
<pre>: (vigenereEncrypt |
<pre>: (vigenereEncrypt |
||
Line 1,765: | Line 3,199: | ||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
<syntaxhighlight lang="pl/i"> |
|||
<lang PL/I> |
|||
cypher: procedure options (main); /* 21 September 2012 */ |
cypher: procedure options (main); /* 21 September 2012 */ |
||
declare t(26) character (26); |
declare t(26) character (26); |
||
Line 1,810: | Line 3,244: | ||
end; |
end; |
||
end cypher; |
end cypher; |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
Message=Meet me on Tuesday evening at seven. |
Message=Meet me on Tuesday evening at seven. |
||
ENCODED='HMKBXEBPXPMYLLYRXIIQTOLTFGZZV'; |
ENCODED='HMKBXEBPXPMYLLYRXIIQTOLTFGZZV'; |
||
Decoded= MEETMEONTUESDAYEVENINGATSEVEN |
Decoded= MEETMEONTUESDAYEVENINGATSEVEN |
||
</pre> |
|||
=={{header|PowerShell}}== |
|||
<syntaxhighlight lang="powershell"># Author: D. Cudnohufsky |
|||
function Get-VigenereCipher |
|||
{ |
|||
Param |
|||
( |
|||
[Parameter(Mandatory=$true)] |
|||
[string] $Text, |
|||
[Parameter(Mandatory=$true)] |
|||
[string] $Key, |
|||
[switch] $Decode |
|||
) |
|||
begin |
|||
{ |
|||
$map = [char]'A'..[char]'Z' |
|||
} |
|||
process |
|||
{ |
|||
$Key = $Key -replace '[^a-zA-Z]','' |
|||
$Text = $Text -replace '[^a-zA-Z]','' |
|||
$keyChars = $Key.toUpper().ToCharArray() |
|||
$Chars = $Text.toUpper().ToCharArray() |
|||
function encode |
|||
{ |
|||
param |
|||
( |
|||
$Char, |
|||
$keyChar, |
|||
$Alpha = [char]'A'..[char]'Z' |
|||
) |
|||
$charIndex = $Alpha.IndexOf([int]$Char) |
|||
$keyIndex = $Alpha.IndexOf([int]$keyChar) |
|||
$NewIndex = ($charIndex + $KeyIndex) - $Alpha.Length |
|||
$Alpha[$NewIndex] |
|||
} |
|||
function decode |
|||
{ |
|||
param |
|||
( |
|||
$Char, |
|||
$keyChar, |
|||
$Alpha = [char]'A'..[char]'Z' |
|||
) |
|||
$charIndex = $Alpha.IndexOf([int]$Char) |
|||
$keyIndex = $Alpha.IndexOf([int]$keyChar) |
|||
$int = $charIndex - $keyIndex |
|||
if ($int -lt 0) { $NewIndex = $int + $Alpha.Length } |
|||
else { $NewIndex = $int } |
|||
$Alpha[$NewIndex] |
|||
} |
|||
while ( $keyChars.Length -lt $Chars.Length ) |
|||
{ |
|||
$keyChars = $keyChars + $keyChars |
|||
} |
|||
for ( $i = 0; $i -lt $Chars.Length; $i++ ) |
|||
{ |
|||
if ( [int]$Chars[$i] -in $map -and [int]$keyChars[$i] -in $map ) |
|||
{ |
|||
if ($Decode) {$Chars[$i] = decode $Chars[$i] $keyChars[$i] $map} |
|||
else {$Chars[$i] = encode $Chars[$i] $keyChars[$i] $map} |
|||
$Chars[$i] = [char]$Chars[$i] |
|||
[string]$OutText += $Chars[$i] |
|||
} |
|||
} |
|||
$OutText |
|||
$OutText = $null |
|||
} |
|||
}</syntaxhighlight> |
|||
Usage examples: |
|||
<pre> |
|||
Encode: |
|||
PS C:\> Get-VigenereCipher 'We attack at dawn.' 'lemon' |
|||
HIMHGLGWOGOEIB |
|||
Decode: |
|||
PS C:\> Get-VigenereCipher 'HIMHGLGWOGOEIB' 'lemon' -Decode |
|||
WEATTACKATDAWN |
|||
</pre> |
</pre> |
||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang="purebasic">Procedure prepString(text.s, Array letters(1)) |
||
;convert characters to an ordinal (0-25) and remove non-alphabetic characters, |
;convert characters to an ordinal (0-25) and remove non-alphabetic characters, |
||
;returns dimension size of result array letters() |
;returns dimension size of result array letters() |
||
Line 1,879: | Line 3,410: | ||
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input() |
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input() |
||
CloseConsole() |
CloseConsole() |
||
EndIf</ |
EndIf</syntaxhighlight> |
||
{{out}} |
|||
Sample output: |
|||
<pre> Plain text = "The quick brown fox jumped over the lazy dogs." |
<pre> Plain text = "The quick brown fox jumped over the lazy dogs." |
||
Encrypted text = "OPKDYZGMJGVAEAWDWYDTGLDCIIOPKYEQCFWVZ" |
Encrypted text = "OPKDYZGMJGVAEAWDWYDTGLDCIIOPKYEQCFWVZ" |
||
Line 1,886: | Line 3,417: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
{{Works with|Python|3}} |
|||
{{trans|Haskell}} |
{{trans|Haskell}} |
||
<syntaxhighlight lang="python">'''Vigenere encryption and decryption''' |
|||
<lang python> |
|||
from itertools import starmap, cycle |
|||
from itertools import starmap, cycle |
|||
def encrypt(message, key): |
|||
def encrypt(message, key): |
|||
# convert to uppercase. |
|||
'''Vigenere encryption of message using key.''' |
|||
# strip out non-alpha characters. |
|||
message = filter(lambda _: _.isalpha(), message.upper()) |
|||
# Converted to uppercase. |
|||
# Non-alpha characters stripped out. |
|||
# single letter encrpytion. |
|||
message = filter(str.isalpha, message.upper()) |
|||
def enc(c,k): return chr(((ord(k) + ord(c)) % 26) + ord('A')) |
|||
def enc(c, k): |
|||
return "".join(starmap(enc, zip(message, cycle(key)))) |
|||
'''Single letter encryption.''' |
|||
def decrypt(message, key): |
|||
return chr(((ord(k) + ord(c) - 2 * ord('A')) % 26) + ord('A')) |
|||
# single letter decryption. |
|||
return ''.join(starmap(enc, zip(message, cycle(key)))) |
|||
def dec(c,k): return chr(((ord(c) - ord(k)) % 26) + ord('A')) |
|||
return "".join(starmap(dec, zip(message, cycle(key)))) |
|||
def decrypt(message, key): |
|||
</lang> |
|||
'''Vigenere decryption of message using key.''' |
|||
Demonstrating: |
|||
<lang python> |
|||
def dec(c, k): |
|||
text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
'''Single letter decryption.''' |
|||
key = "VIGENERECIPHER" |
|||
return chr(((ord(c) - ord(k) - 2 * ord('A')) % 26) + ord('A')) |
|||
encr = encrypt(text, key) |
|||
decr = decrpyt(encr, key) |
|||
return ''.join(starmap(dec, zip(message, cycle(key)))) |
|||
print text |
|||
print encr |
|||
def main(): |
|||
print decr |
|||
'''Demonstration''' |
|||
</lang> |
|||
Output: |
|||
text = 'Beware the Jabberwock, my son! The jaws that bite, ' + ( |
|||
<pre> |
|||
'the claws that catch!' |
|||
) |
|||
key = 'VIGENERECIPHER' |
|||
encr = encrypt(text, key) |
|||
decr = decrypt(encr, key) |
|||
print(text) |
|||
print(encr) |
|||
print(decr) |
|||
if __name__ == '__main__': |
|||
main() |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
||
</pre> |
|||
=={{header|Quackery}}== |
|||
<syntaxhighlight lang="quackery"> [ [] swap witheach |
|||
[ upper |
|||
dup char A char Z 1+ within |
|||
iff join else drop ] ] is onlycaps ( $ --> $ ) |
|||
[ onlycaps |
|||
[] swap witheach |
|||
[ char A - join ] ] is cipherdisk ( $ --> [ ) |
|||
[ [] swap witheach |
|||
[ 26 swap - join ] ] is deciphering ( [ --> [ ) |
|||
[ behead tuck join swap ] is nextkey ( [ --> [ n ) |
|||
[ dip nextkey + dup |
|||
char Z > if [ 26 - ] ] is encryptchar ( [ c --> [ c ) |
|||
[ $ "" swap rot |
|||
onlycaps witheach |
|||
[ encryptchar |
|||
swap dip join ] |
|||
drop ] is vigenere ( $ [ --> $ ) |
|||
[ cipherdisk vigenere ] is encrypt ( $ $ --> $ ) |
|||
[ cipherdisk deciphering vigenere ] is decrypt ( $ $ --> $ ) |
|||
$ "If you reveal your secrets to the wind, you should " |
|||
$ "not blame the wind for revealing them to the trees." join |
|||
say "Encrypted: " $ "Kahlil Gibran" encrypt dup echo$ cr |
|||
say "Decrypted: " $ "Kahlil Gibran" decrypt echo$</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Encrypted: SFFZCCKDFRLLYUYDMNXMUJTBDHLHQYJGPLSUYUSOVZZJMRMRDHLHQYJNPIRRFEHWQYMBIVMGYTOPBCKMT |
|||
Decrypted: IFYOUREVEALYOURSECRETSTOTHEWINDYOUSHOULDNOTBLAMETHEWINDFORREVEALINGTHEMTOTHETREES</pre> |
|||
=={{header|R}}== |
=={{header|R}}== |
||
< |
<syntaxhighlight lang="r">mod1 = function(v, n) |
||
# mod1(1:20, 6) => 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 |
# mod1(1:20, 6) => 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2 |
||
((v - 1) %% n) + 1 |
((v - 1) %% n) + 1 |
||
Line 1,945: | Line 3,533: | ||
# WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
# WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
message(vigen("WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY", "vigenerecipher", decrypt = T)) |
message(vigen("WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY", "vigenerecipher", decrypt = T)) |
||
# BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</ |
# BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</syntaxhighlight> |
||
=={{header|Racket}}== |
|||
<syntaxhighlight lang="racket"> |
|||
#lang racket |
|||
(define chr integer->char) |
|||
(define ord char->integer) |
|||
(define (encrypt msg key) |
|||
(define cleaned |
|||
(list->string |
|||
(for/list ([c (string-upcase msg)] |
|||
#:when (char-alphabetic? c)) c))) |
|||
(list->string |
|||
(for/list ([c cleaned] [k (in-cycle key)]) |
|||
(chr (+ (modulo (+ (ord c) (ord k)) 26) (ord #\A)))))) |
|||
(define (decrypt msg key) |
|||
(list->string |
|||
(for/list ([c msg] [k (in-cycle key)]) |
|||
(chr (+ (modulo (- (ord c) (ord k)) 26) (ord #\A)))))) |
|||
(decrypt (encrypt "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
"VIGENERECIPHER") |
|||
"VIGENERECIPHER") |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<syntaxhighlight lang="racket"> |
|||
"BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH" |
|||
</syntaxhighlight> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{Works with|rakudo|2015-11-14}} |
|||
<syntaxhighlight lang="raku" line>sub s2v ($s) { $s.uc.comb(/ <[ A..Z ]> /)».ord »-» 65 } |
|||
sub v2s (@v) { (@v »%» 26 »+» 65)».chr.join } |
|||
sub blacken ($red, $key) { v2s(s2v($red) »+» s2v($key)) } |
|||
sub redden ($blk, $key) { v2s(s2v($blk) »-» s2v($key)) } |
|||
my $red = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"; |
|||
my $key = "Vigenere Cipher!!!"; |
|||
say $red; |
|||
say my $black = blacken($red, $key); |
|||
say redden($black, $key);</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
|||
This is a natural job for hyperoperators, which can vectorize any operator. |
|||
For infix operators the pointy end indicates which side to "dwim", repeating |
|||
elements on that side until the other side runs out. In particular, repeating |
|||
the key naturally falls out of this cyclic dwimmery, as does repeating the various constants to be applied with any of several operations to every element of the list. Factoring out the canonicalization and decanonicalization lets us see quite clearly that the only difference between encryption and decryptions is the sign of the vector addition/subtraction. Since hyperops are inherently parallelizable, this algorithm might run well in your GPU. |
|||
=={{header|Red}}== |
|||
note: this program is much longer than it needed to be - because i couldn't resist |
|||
to add some more features to make it actually "useful" :-) So not only can u encrypt any character (because the crypted message will be base 64 encoded), but it also includes a Gui. |
|||
the Gui window has buttons to access the clipboard too - so u can get the original text from clipboard and put the crypted message back again. To execute it,simply download the latest red.exe (about 1,1 MB size! ) from red-lang.org. This program can also be compiled to an .exe (+ red runtime.dll ) by simply execute <pre>red.exe -c vign1.red</pre> or <pre>red.exe -r vign1.red</pre> which creates a single .exe file whithout the need for any .dll . should be working on windows , linux ( under wine ) and mac OS. |
|||
<syntaxhighlight lang="red">Red [needs: 'view] |
|||
CRLF: copy "^M^/" ;; constant for 0D 0A line feed |
|||
;;------------------------------------ |
|||
crypt: func ["function to en- or decrypt message from textarea tx1" |
|||
/decrypt "decrypting switch/refinement" ][ |
|||
;;------------------------------------ |
|||
;; when decrypting we have to remove the superflous newlines |
|||
;; and undo the base64 encoding first ... |
|||
txt: either decrypt [ ;; message to en- or decrypt |
|||
s: copy tx1/text |
|||
;; newline could be single 0a byte or crlf sequence when copied from clipboard... |
|||
debase replace/all s either find s CRLF [CRLF ] [ newline ] "" |
|||
] [ |
|||
tx1/text ;; plaintext message |
|||
] |
|||
txt: to-binary txt ;; handle message as binary |
|||
key: to-binary key1/text ;; handle key also as binary |
|||
bin: copy either decrypt [ "" ][ #{} ] ;; buffer for output |
|||
code: copy #{} ;; temp field to collect utf8 bytes when decrypting |
|||
;; loop over length of binary! message ... |
|||
repeat pos length? txt [ |
|||
k: to-integer key/(1 + modulo pos length? key) ;; get corresponding key byte |
|||
c: to-integer txt/:pos ;; get integer value from message byte at position pos |
|||
either decrypt [ ;; decrypting ? |
|||
c: modulo ( 256 + c - k ) 256 ;; compute original byte value |
|||
case [ |
|||
;; byte starting with 11.... ( >= 192 dec ) is utf8 startbyte |
|||
;; byte starting with 10... ( >= 128 dec) is utf8 follow up byte , below is single ascii byte |
|||
( c >= 192 ) or ( c < 128 ) [ ;; starting utf8 sequence byte or below 128 normal ascii ? |
|||
;; append last code to buffer, maybe normal ascii or utf8 sequence... |
|||
if not empty? code [ append bin to-char code ] ;; save previous code first |
|||
code: append copy #{} c ;; start new code |
|||
] |
|||
true [ append code c ] ;; otherwise utf8 follow up byte, append to startbyte |
|||
] |
|||
][ |
|||
append bin modulo ( c + k ) 256 ;; encrypting , simply collect binary bytes |
|||
] |
|||
] ;; close repeat loop |
|||
either decrypt [ ;; collect utf-8 characters |
|||
append bin to-char code ;; append last code |
|||
tx2/text: to-string bin ;; create valid utf8 string when decrypting |
|||
][ ;; base64 encoding of crypted binary to get readable text string... |
|||
s: enbase copy bin ;; base 64 is default |
|||
while [40 < length? s ] [ ;; insert newlines for better "readability" |
|||
s: skip s either head? s [40][41] ;; ... every 40 characters |
|||
insert s newline |
|||
] |
|||
tx2/text: head s ;; reset s pointing to head again |
|||
] |
|||
] |
|||
;---------------------------------------------------------- |
|||
; start of program |
|||
;---------------------------------------------------------- |
|||
view layout [title "vigenere cyphre" ;Define nice GUI :- ) |
|||
;---------------------------------------------------------- |
|||
backdrop silver ;; define window background colour |
|||
text "message:" pad 99x1 button "get-clip" [tx1/text: read-clipboard] |
|||
;; code in brackets will be executed, when button is clicked: |
|||
button "clear" [tx1/text: copy "" ] return |
|||
tx1: area 330x80 "" return |
|||
text 25x20 "Key:" key1: field 290x20 "secretkey" return |
|||
button "crypt" [crypt ] button "decrypt" [crypt/decrypt ] |
|||
button "swap" [tx1/text: copy tx2/text tx2/text: copy "" ] return |
|||
text "de-/encrypted message:" pad 50x1 button "copy clip" [ write-clipboard tx2/text] |
|||
button "clear" [tx2/text: copy "" ] return |
|||
tx2: area 330x100 return |
|||
pad 270x1 button "Quit " [quit] |
|||
] |
|||
</syntaxhighlight> |
|||
{{output}} |
|||
the message <pre>Beware the Jabberwock, my son! The jaws that bite, the claws that catch!</pre> with key "VIGENERECIPHER" translates to <pre>i6y8r7e3ZbextWiPs7irrLfFtLWwb2m9wWXFxbdo |
|||
ZaKtt2Wtqse7Zca+qrtlsK7Gqm9pxLCqcrm1qLzBZcatpL1wq6bGubFo</pre> |
|||
decrypting returns the original message <pre>Beware the Jabberwock, my son! The jaws that bite, the claws that catch!</pre> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
===uppercase text only=== |
===uppercase text only=== |
||
< |
<syntaxhighlight lang="rexx">/*REXX program encrypts (and displays) uppercased text using the Vigenère cypher.*/ |
||
@.1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
@.1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
||
L=length(@.1) |
L=length(@.1) |
||
do j=2 to L; jm=j-1; q=@.jm |
do j=2 to L; jm=j-1; q=@.jm |
||
@.j=substr(q,2,L-1)left(q,1) |
@.j=substr(q, 2, L - 1)left(q, 1) |
||
end /*j*/ |
end /*j*/ |
||
cypher = space('WHOOP DE DOO NO BIG DEAL HERE OR THERE',0) |
cypher = space('WHOOP DE DOO NO BIG DEAL HERE OR THERE', 0) |
||
oMsg = 'People solve problems by trial and error; judgement helps pick the trial.' |
oMsg = 'People solve problems by trial and error; judgement helps pick the trial.' |
||
oMsgU = oMsg; upper oMsgU |
oMsgU = oMsg; upper oMsgU |
||
cypher_=copies(cypher,length(oMsg)%length(cypher)) |
cypher_= copies(cypher, length(oMsg) % length(cypher) ) |
||
say ' original text =' oMsg |
say ' original text =' oMsg |
||
xMsg= Ncypher(oMsgU); say ' cyphered text =' xMsg |
|||
bMsg= Dcypher(xMsg) ; say 're-cyphered text =' bMsg |
|||
bMsg=Dcypher(xMsg) |
|||
say 're-cyphered text =' bMsg |
|||
exit |
exit |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
/*───────────────────────────────Ncypher subroutine─────────────────────*/ |
|||
Ncypher: parse arg |
Ncypher: parse arg x; nMsg=; #=1 /*unsupported char? ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ |
||
do i=1 for length( |
do i=1 for length(x); j=pos(substr(x,i,1), @.1); if j==0 then iterate |
||
nMsg=nMsg || substr(@.j, pos( substr( cypher_, #, 1), @.1), 1); #=#+1 |
|||
if \datatype(x,'U') then iterate /*not a letter? Then ignore it.*/ |
|||
end /*j*/ |
|||
j=pos(x,@.1); nMsg=nMsg || substr(@.j,pos(substr(cypher_,#,1),@.1),1) |
|||
return nMsg |
|||
#=#+1 /*bump the character counter. */ |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
end |
|||
Dcypher: parse arg x; dMsg= |
|||
return nMsg |
|||
do i=1 for length(x); j=pos(substr(cypher_, i, 1), @.1) |
|||
/*───────────────────────────────Dcypher subroutine──────────────────────*/ |
|||
dMsg=dMsg || substr(@.1, pos( substr(x, i, 1), @.j), 1 ) |
|||
Dcypher: parse arg stuff; #=1; dMsg= |
|||
end /*j*/ |
|||
return dMsg</syntaxhighlight> |
|||
j=pos(x,@.1); dMsg=dMsg || substr(@.1, pos(substr(stuff,i,1),@.j),1) |
|||
{{out|output|text= when using the default internal fields:}} |
|||
end |
|||
<pre> |
|||
return dMsg</lang> |
|||
'''output''' (using the internal fields) |
|||
<pre style="overflow:scroll"> |
|||
original text = People solve problems by trial and error; judgement helps pick the trial. |
original text = People solve problems by trial and error; judgement helps pick the trial. |
||
cyphered text = LLCDAHWRZJRDSWHOIMDICKVWREHRUINYCFYXHJSARBUPKOTSAPGBXVVMYMRP |
cyphered text = LLCDAHWRZJRDSWHOIMDICKVWREHRUINYCFYXHJSARBUPKOTSAPGBXVVMYMRP |
||
re-cyphered text = PEOPLESOLVEPROBLEMSBYTRIALANDERRORJUDGEMENTHELPSPICKTHETRIAL |
re-cyphered text = PEOPLESOLVEPROBLEMSBYTRIALANDERRORJUDGEMENTHELPSPICKTHETRIAL |
||
</pre> |
</pre> |
||
===supports most characters=== |
===supports most characters=== |
||
This version supports all characters on the IBM Model M keyboard, including blanks |
This version supports all characters on the IBM Model M keyboard, including blanks, but any other |
||
<br> |
<br>characters can be added as long as they're viewable. |
||
<lang rexx>/*REXX program encrypts uppercased text using the Vigenère cypher. */ |
|||
Additional characters can be added by simply appending them to the <big>'''@.1'''</big> variable. |
|||
@abc='abcdefghijklmnopqrstuvwxyz'; @abcU=@abc; upper @abcU |
|||
<syntaxhighlight lang="rexx">/*REXX program encrypts (and displays) most text using the Vigenère cypher. */ |
|||
@abc= 'abcdefghijklmnopqrstuvwxyz'; @abcU=@abc; upper @abcU |
|||
@.1 = @abcU || @abc'0123456789~`!@#$%^&*()_-+={}|[]\:;<>?,./" ''' |
@.1 = @abcU || @abc'0123456789~`!@#$%^&*()_-+={}|[]\:;<>?,./" ''' |
||
L=length(@.1) |
L=length(@.1) |
||
do j=2 to length(@.1); jm=j-1; q=@.jm |
do j=2 to length(@.1); jm=j - 1; q=@.jm |
||
@.j=substr(q,2, |
@.j=substr(q, 2, L - 1)left(q, 1) |
||
end /*j*/ |
end /*j*/ |
||
cypher = space('WHOOP DE DOO NO BIG DEAL HERE OR THERE',0) |
cypher = space('WHOOP DE DOO NO BIG DEAL HERE OR THERE', 0) |
||
oMsg = 'Making things easy is just knowing the shortcuts. --- Gerard J. Schildberger' |
oMsg = 'Making things easy is just knowing the shortcuts. --- Gerard J. Schildberger' |
||
cypher_=copies(cypher,length(oMsg)%length(cypher)) |
cypher_= copies(cypher, length(oMsg) % length(cypher) ) |
||
say ' original text =' oMsg |
say ' original text =' oMsg |
||
xMsg= Ncypher(oMsg); say ' cyphered text =' xMsg |
|||
bMsg= Dcypher(xMsg); say 're-cyphered text =' bMsg |
|||
bMsg=Dcypher(xMsg) |
|||
say 're-cyphered text =' bMsg |
|||
exit |
exit |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
/*───────────────────────────────Ncypher subroutine─────────────────────*/ |
|||
Ncypher: parse arg |
Ncypher: parse arg x; nMsg=; #=1 /*unsupported char? ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ |
||
do i=1 for length( |
do i=1 for length(x); j=pos(substr(x,i,1), @.1); if j==0 then iterate |
||
nMsg=nMsg || substr(@.j, pos( substr( cypher_, #, 1), @.1), 1); #=# + 1 |
|||
j=pos(x,@.1); if j==0 then iterate /*character not supported? Ignore*/ |
|||
end /*j*/ |
|||
nMsg=nMsg || substr(@.j,pos(substr(cypher_,#,1),@.1),1); #=#+1 |
|||
return nMsg |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
return nMsg |
|||
Dcypher: parse arg x; dMsg= |
|||
/*───────────────────────────────Dcypher subroutine──────────────────────*/ |
|||
do i=1 for length(x); j=pos(substr(cypher_, i, 1), @.1) |
|||
Dcypher: parse arg stuff; #=1; dMsg= |
|||
dMsg=dMsg || substr(@.1, pos( substr(x, i, 1), @.j), 1 ) |
|||
end /*j*/ |
|||
j=pos(x,@.1); dMsg=dMsg || substr(@.1, pos(substr(stuff,i,1),@.j),1) |
|||
return dMsg</syntaxhighlight> |
|||
end /*j*/ |
|||
{{out|output|text= when using the default internal fields:}} |
|||
return dMsg</lang> |
|||
<pre> |
|||
'''output''' |
|||
<pre style="overflow:scroll"> |
|||
original text = Making things easy is just knowing the shortcuts. --- Gerard J. Schildberger |
original text = Making things easy is just knowing the shortcuts. --- Gerard J. Schildberger |
||
cyphered text = ihyw2jCwvw0utGkdwyJpwPn89!Fo4s&p1uNwlhM6u2s1ixxsGF}"}MXxye8h/H?/QafgjbZcpecp |
cyphered text = ihyw2jCwvw0utGkdwyJpwPn89!Fo4s&p1uNwlhM6u2s1ixxsGF}"}MXxye8h/H?/QafgjbZcpecp |
||
Line 2,026: | Line 3,750: | ||
</pre> |
</pre> |
||
=={{header| |
=={{header|Ring}}== |
||
<syntaxhighlight lang="ring"> |
|||
<lang Ruby>class VigenereCipher |
|||
# Project : Vigenère cipher |
|||
key = "LEMON" |
|||
BASE = 'A'.ord |
|||
plaintext = "ATTACK AT DAWN" |
|||
SIZE = 'Z'.ord - BASE + 1 |
|||
ciphertext = encrypt(plaintext, key) |
|||
see "key = "+ key + nl |
|||
see "plaintext = " + plaintext + nl |
|||
see "ciphertext = " + ciphertext + nl |
|||
see "decrypted = " + decrypt(ciphertext, key) + nl |
|||
def key=(key) |
|||
func encrypt(plain, key) |
|||
@key = key.upcase.gsub(/[^A-Z]/, '') |
|||
o = "" |
|||
end |
|||
k = 0 |
|||
plain = fnupper(plain) |
|||
key = fnupper(key) |
|||
for i = 1 to len(plain) |
|||
n = ascii(plain[i]) |
|||
if n >= 65 and n <= 90 |
|||
o = o + char(65 + (n + ascii(key[k+1])) % 26) |
|||
k = (k + 1) % len(key) |
|||
ok |
|||
next |
|||
return o |
|||
func decrypt(cipher, key) |
|||
o = "" |
|||
k = 0 |
|||
cipher = fnupper(cipher) |
|||
key = fnupper(key) |
|||
for i = 1 to len(cipher) |
|||
n = ascii(cipher[i]) |
|||
o = o + char(65 + (n + 26 - ascii(key[k+1])) % 26) |
|||
k = (k + 1) % len(key) |
|||
next |
|||
return o |
|||
func fnupper(a) |
|||
for aa = 1 to len(a) |
|||
c = ascii(a[aa]) |
|||
if c >= 97 and c <= 122 |
|||
a[aa] = char(c-32) |
|||
ok |
|||
next |
|||
return a |
|||
</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
key = LEMON |
|||
plaintext = ATTACK AT DAWN |
|||
ciphertext = LXFOPVEFRNHR |
|||
decrypted = ATTACKATDAWN |
|||
</pre> |
|||
=={{header|RPL}}== |
|||
def initialize(key) |
|||
As the encoding and decoding programs would differ by only one instruction (plus instead of minus), they have been merged into a single function that decodes if the input text is in uppercase only, and encodes otherwise. To encode a uppercase-only text, a space (or any punctuation sign) must be put somwehere. |
|||
self.key= key |
|||
≪ → key |
|||
end |
|||
≪ 1 CF { } |
|||
1 3 PICK SIZE '''FOR''' j |
|||
OVER j DUP SUB NUM |
|||
'''IF''' DUP 97 ≥ OVER 122 ≤ AND '''THEN''' 32 - '''END''' |
|||
'''IF''' DUP 65 ≥ OVER 90 ≤ AND '''THEN''' 65 - + '''ELSE''' 1 SF DROP '''END''' |
|||
'''NEXT''' |
|||
SWAP DROP "" |
|||
1 3 PICK SIZE '''FOR''' j |
|||
OVER j GET |
|||
key j 1 - key SIZE MOD 1 + DUP SUB NUM 64 - |
|||
'''IF''' 1 FC? '''THEN''' + '''ELSE''' - '''END''' |
|||
26 MOD 65 + CHR + |
|||
'''NEXT''' |
|||
SWAP DROP |
|||
≫ ≫ ‘<span style="color:blue">VIGENERE</span>’ STO |
|||
"Beware the Jabberwock!" <span style="color:blue">VIGENERE</span> |
|||
def encrypt(text) |
|||
DUP <span style="color:blue">VIGENERE</span> |
|||
crypt(text, :+) |
|||
{{out}} |
|||
end |
|||
<pre> |
|||
2: "FVPVDZBCIATWNZZRSTD" |
|||
1: "BEWARETHEJABBERWOCK" |
|||
</pre> |
|||
=={{header|Ruby}}== |
|||
def decrypt(text) |
|||
<syntaxhighlight lang="ruby">module VigenereCipher |
|||
crypt(text, :-) |
|||
BASE = 'A'.ord |
|||
SIZE = 'Z'.ord - BASE + 1 |
|||
def encrypt(text, key) |
|||
crypt(text, key, :+) |
|||
end |
end |
||
def |
def decrypt(text, key) |
||
crypt(text, key, :-) |
|||
plaintext = text.upcase.gsub(/[^A-Z]/, '') |
|||
end |
|||
key_iterator = @key.chars.cycle |
|||
ciphertext = '' |
|||
def crypt(text, key, dir) |
|||
plaintext.each_char do |plain_char| |
|||
text = text.upcase.gsub(/[^A-Z]/, '') |
|||
key_iterator = key.upcase.gsub(/[^A-Z]/, '').chars.map{|c| c.ord - BASE}.cycle |
|||
ciphertext += |
|||
text.each_char.inject('') do |ciphertext, char| |
|||
((plain_char.ord - BASE).send(dir, offset) % SIZE + BASE).chr |
|||
offset = key_iterator.next |
|||
ciphertext << ((char.ord - BASE).send(dir, offset) % SIZE + BASE).chr |
|||
end |
end |
||
return ciphertext |
|||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
Demonstration: |
Demonstration: |
||
<lang |
<syntaxhighlight lang="ruby">include VigenereCipher |
||
plaintext = 'Beware the Jabberwock, my son! The jaws that bite, the claws that catch!' |
plaintext = 'Beware the Jabberwock, my son! The jaws that bite, the claws that catch!' |
||
key = 'Vigenere cipher' |
|||
ciphertext = vc.encrypt(plaintext) |
|||
ciphertext = VigenereCipher.encrypt(plaintext, key) |
|||
recovered = vc.decrypt(ciphertext) |
|||
recovered = VigenereCipher.decrypt(ciphertext, key) |
|||
puts "Original: #{plaintext}" |
puts "Original: #{plaintext}" |
||
puts "Encrypted: #{ciphertext}" |
puts "Encrypted: #{ciphertext}" |
||
puts "Decrypted: #{recovered}"</ |
puts "Decrypted: #{recovered}"</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre> |
|||
Original: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
||
</pre> |
|||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
<syntaxhighlight lang="rust">use std::ascii::AsciiExt; |
|||
<lang Rust>fn uppercase_and_filter(in: &str) -> ~[u8] { |
|||
let mut result = ~[]; |
|||
static A: u8 = 'A' as u8; |
|||
for in.each_char |c| { |
|||
if char::is_ascii(c) { |
|||
fn uppercase_and_filter(input: &str) -> Vec<u8> { |
|||
if char::is_lowercase(c) { |
|||
let alphabet = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
|||
// We know it's ascii, so just do the math directly |
|||
let mut result = Vec::new(); |
|||
} else if char::is_uppercase(c) { |
|||
for c in input.chars() { |
|||
// Ignore anything that is not in our short list of chars. We can then safely cast to u8. |
|||
} |
|||
if alphabet.iter().any(|&x| x as char == c) { |
|||
result.push(c.to_ascii_uppercase() as u8); |
|||
} |
} |
||
} |
} |
||
Line 2,096: | Line 3,897: | ||
} |
} |
||
fn vigenere(key: &str, text: &str, is_encoding: bool) -> |
fn vigenere(key: &str, text: &str, is_encoding: bool) -> String { |
||
const A: u8 = 'A' as u8; |
|||
let key_bytes = uppercase_and_filter(key); |
let key_bytes = uppercase_and_filter(key); |
||
let text_bytes = uppercase_and_filter(text); |
let text_bytes = uppercase_and_filter(text); |
||
let mut result_bytes = |
let mut result_bytes = Vec::new(); |
||
for |
for (i, c) in text_bytes.iter().enumerate() { |
||
let c2 = if is_encoding { |
let c2 = if is_encoding { |
||
(c + key_bytes[i % key_bytes.len()] - 2 * A) % 26 + A |
(c + key_bytes[i % key_bytes.len()] - 2 * A) % 26 + A |
||
} else { |
} else { |
||
(c - key_bytes[i % key_bytes.len()] |
(c + 26 - key_bytes[i % key_bytes.len()]) % 26 + A |
||
}; |
}; |
||
result_bytes.push(c2); |
result_bytes.push(c2); |
||
} |
} |
||
String::from_utf8(result_bytes).unwrap() |
|||
} |
} |
||
Line 2,120: | Line 3,920: | ||
let key = "VIGENERECIPHER"; |
let key = "VIGENERECIPHER"; |
||
println!("Text: {}", text); |
|||
println!("Key: {}", key); |
|||
let encoded = vigenere(key, text, true); |
let encoded = vigenere(key, text, true); |
||
println!("Code: {}", encoded); |
|||
let decoded = vigenere(key, encoded, false); |
let decoded = vigenere(key, &encoded, false); |
||
println!("Back: {}", decoded); |
|||
}</syntaxhighlight> |
|||
} |
|||
</lang> |
|||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
Valid characters for messages: A through Z, zero, 1 to 9, and full-stop (.) |
Valid characters for messages: A through Z, zero, 1 to 9, and full-stop (.) |
||
<syntaxhighlight lang="scala"> |
|||
<lang scala>import scala.language.implicitConversions |
|||
object Vigenere { |
|||
def encrypt(msg: String, key: String) : String = { |
|||
var result: String = "" |
|||
var j = 0 |
|||
for (i <- 0 to msg.length - 1) { |
|||
// |
|||
val c = msg.charAt(i) |
|||
// Translate Special Chars to Names |
|||
if (c >= 'A' && c <= 'Z') { |
|||
// -------------------------------- |
|||
result += ((c + key.charAt(j) - 2 * 'A') % 26 + 'A').toChar |
|||
// |
|||
j = (j + 1) % key.length |
|||
class VText |
|||
} |
|||
} |
|||
return result |
|||
class KeyText( key:String ) extends VText { |
|||
} |
|||
override def toString = key |
|||
} |
|||
def decrypt(msg: String, key: String) : String = { |
|||
object KeyText { |
|||
var result: String = "" |
|||
def apply(k:String) = new KeyText( "[^A-Z]*".r.replaceAllIn(k.toUpperCase,"") ) |
|||
var j = 0 |
|||
} |
|||
for (i <- 0 to msg.length - 1) { |
|||
val c = msg.charAt(i) |
|||
if (c >= 'A' && c <= 'Z') { |
|||
result += ((c - key.charAt(j) + 26) % 26 + 'A').toChar |
|||
j = (j + 1) % key.length |
|||
} |
|||
} |
|||
return result |
|||
class PlainText( message:String ) extends VText { |
|||
override def toString = { |
|||
"[^A-Z]*".r.replaceAllIn(message.toUpperCase,"") |
|||
.replaceAll("FULLSTOP",".") |
|||
.replaceAll("CERO","0") |
|||
.replaceAll("EINZ","1") |
|||
.replaceAll("ZWEI","2") |
|||
.replaceAll("TRES","3") |
|||
.replaceAll("CUATRO","4") |
|||
.replaceAll("CINQ","5") |
|||
.replaceAll("SECHS","6") |
|||
.replaceAll("SIETE","7") |
|||
.replaceAll("HUIT","8") |
|||
.replaceAll("NEUF","9") |
|||
} |
} |
||
def toRawString = message |
|||
} |
|||
object PlainText { |
|||
def apply(k:String) = new PlainText( k.toList.map(_.toString).map { |
|||
case "0" => "CERO" |
|||
case "1" => "EINZ" |
|||
case "2" => "ZWEI" |
|||
case "3" => "TRES" |
|||
case "4" => "CUATRO" |
|||
case "5" => "CINQ" |
|||
case "6" => "SECHS" |
|||
case "7" => "SIETE" |
|||
case "8" => "HUIT" |
|||
case "9" => "NEUF" |
|||
case "." => "FULLSTOP" |
|||
case a:String => "[^A-Z]*".r.replaceAllIn(a.toUpperCase,"") |
|||
}.mkString ) |
|||
} |
|||
class CipherText( cipher:String ) extends VText { |
|||
override def toString = cipher |
|||
} |
|||
object CipherText { |
|||
def apply(k:String) = new CipherText( |
|||
"[^A-Z]*".r.replaceAllIn(k.toUpperCase,"") |
|||
) |
|||
} |
|||
// |
|||
// The Vigenère Cipher |
|||
// ------------------- |
|||
// |
|||
def vcipher( key:KeyText )( plaintext:PlainText ) : CipherText = { |
|||
val k = key.toString |
|||
val p = plaintext.toRawString |
|||
val kp = (k * (p.length / k.length + 1)) zip (p) |
|||
CipherText( (for( t <- kp; k = (t._1 - 'A'); p = (t._2 - 'A'); a = 'A' + (p + k) % 26 ) yield (a.toChar)).mkString ) |
|||
} |
} |
||
println("Encrypt text ABC => " + Vigenere.encrypt("ABC", "KEY")) |
|||
def vdecipher( key:KeyText )( ciphertext:CipherText ) : PlainText = { |
|||
println("Decrypt text KFA => " + Vigenere.decrypt("KFA", "KEY")) |
|||
val k = key.toString |
|||
</syntaxhighlight> |
|||
val c = ciphertext.toString |
|||
val kc = (k * (c.length / k.length + 1)) zip (c) |
|||
PlainText( (for( t <- kc; k = (t._1 - 'A'); c = (t._2 - 'A'); a = 'A' + (26 + c - k) % 26 ) yield (a.toChar)).mkString ) |
|||
} |
|||
// Use Implicits to overcome the ambiguity problem of overloaded partial functions |
|||
implicit def VTextToString( v:VText ) : String = v match { |
|||
case k:KeyText => k.toString |
|||
case p:PlainText => p.toString |
|||
case c:CipherText => c.toString |
|||
case _ => "" |
|||
} |
|||
implicit def StringToKeyText( s:String ) = KeyText(s) |
|||
implicit def StringToPlainText( s:String ) = PlainText(s) |
|||
implicit def StringToCipherText( s:String ) = CipherText(s) |
|||
// Validate cipher/decipher |
|||
assert( vcipher("LEMON")("ATTACKATDAWN").toString == "LXFOPVEFRNHR" ) |
|||
assert( vdecipher("LEMON")("LXFOPVEFRNHR").toString == "ATTACKATDAWN" ) |
|||
// A quick test |
|||
val todaysKey = "lemon" |
|||
val todaysCipher = vcipher(todaysKey) _ |
|||
val todaysDecipher = vdecipher(todaysKey) _ |
|||
val plaintext = "Attack at 0620." |
|||
val ciphertext = todaysCipher(plaintext) |
|||
println( " Message: " + plaintext + "\n" ) |
|||
println( "Enciphered: " + ciphertext + "\n" ) |
|||
println( "Deciphered: " + todaysDecipher( ciphertext ) + "\n" ) |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>scala> Encrypt text ABC => KFA |
|||
<pre> Message: Attack at 0620. |
|||
scala> Decrypt text KFA => ABC</pre> |
|||
Enciphered: LXFOPVEFQRCSESPSWLKRTGQFBQYXZFESB |
|||
Deciphered: ATTACKAT0620. |
|||
</pre> |
|||
=={{header|Seed7}}== |
=={{header|Seed7}}== |
||
< |
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i"; |
||
const func string: vigenereCipher (in string: source, in var string: keyword) is func |
const func string: vigenereCipher (in string: source, in var string: keyword) is func |
||
Line 2,306: | Line 4,023: | ||
decrypted := vigenereDecipher(encrypted, keyword); |
decrypted := vigenereDecipher(encrypted, keyword); |
||
writeln("Decrypted: " <& decrypted); |
writeln("Decrypted: " <& decrypted); |
||
end func;</ |
end func;</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
Input: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
Input: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
||
Line 2,314: | Line 4,031: | ||
Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
||
</pre> |
|||
=={{header|Sidef}}== |
|||
{{trans|Raku}} |
|||
<syntaxhighlight lang="ruby">func s2v(s) { s.uc.scan(/[A-Z]/).map{.ord} »-» 65 } |
|||
func v2s(v) { v »%» 26 »+» 65 -> map{.chr}.join } |
|||
func blacken (red, key) { v2s(s2v(red) »+« s2v(key)) } |
|||
func redden (blk, key) { v2s(s2v(blk) »-« s2v(key)) } |
|||
var red = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
var key = "Vigenere Cipher!!!" |
|||
say red |
|||
say (var black = blacken(red, key)) |
|||
say redden(black, key)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
</pre> |
</pre> |
||
Line 2,319: | Line 4,057: | ||
in the following code, the cypher should consist of upper-case characters only. If that is not guaranteed, apply prep to it before passing it to encrypt/decrypt.. |
in the following code, the cypher should consist of upper-case characters only. If that is not guaranteed, apply prep to it before passing it to encrypt/decrypt.. |
||
{{works with|Smalltalk/X}} |
{{works with|Smalltalk/X}} |
||
< |
<syntaxhighlight lang="smalltalk"> |
||
prep := [:s | s select:[:ch | ch isLetter] thenCollect:[:ch | ch asUppercase]]. |
prep := [:s | s select:[:ch | ch isLetter] thenCollect:[:ch | ch asUppercase]]. |
||
encrypt := [:s :cypher | (prep value:s) keysAndValuesCollect:[:i :ch | ch rot:((cypher at:((i-1)\\key size+1))-$A) ]]. |
encrypt := [:s :cypher | (prep value:s) keysAndValuesCollect:[:i :ch | ch rot:((cypher at:((i-1)\\key size+1))-$A) ]]. |
||
decrypt := [:s :cypher | (prep value:s) keysAndValuesCollect:[:i :ch | ch rot:26-((cypher at:((i-1)\\key size+1))-$A) ]]. |
decrypt := [:s :cypher | (prep value:s) keysAndValuesCollect:[:i :ch | ch rot:26-((cypher at:((i-1)\\key size+1))-$A) ]]. |
||
</syntaxhighlight> |
|||
</lang> |
|||
Test: |
Test: |
||
< |
<syntaxhighlight lang="smalltalk"> |
||
plain := 'Beware the Jabberwock, my son! The jaws that bite, the claws that catch!'. |
plain := 'Beware the Jabberwock, my son! The jaws that bite, the claws that catch!'. |
||
cypher := 'VIGENERECIPHER'. |
cypher := 'VIGENERECIPHER'. |
||
Line 2,333: | Line 4,071: | ||
crypted -> 'WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY' |
crypted -> 'WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY' |
||
plain2 -> 'BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH' |
plain2 -> 'BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH' |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Swift}}== |
|||
Can support a larger range of characters, if desired |
|||
<syntaxhighlight lang="swift">public func convertToUnicodeScalars( |
|||
str: String, |
|||
minChar: UInt32, |
|||
maxChar: UInt32 |
|||
) -> [UInt32] { |
|||
var scalars = [UInt32]() |
|||
for scalar in str.unicodeScalars { |
|||
let val = scalar.value |
|||
guard val >= minChar && val <= maxChar else { |
|||
continue |
|||
} |
|||
scalars.append(val) |
|||
} |
|||
return scalars |
|||
} |
|||
public struct Vigenere { |
|||
private let keyScalars: [UInt32] |
|||
private let smallestScalar: UInt32 |
|||
private let largestScalar: UInt32 |
|||
private let sizeAlphabet: UInt32 |
|||
public init?(key: String, smallestCharacter: Character = "A", largestCharacter: Character = "Z") { |
|||
let smallScalars = smallestCharacter.unicodeScalars |
|||
let largeScalars = largestCharacter.unicodeScalars |
|||
guard smallScalars.count == 1, largeScalars.count == 1 else { |
|||
return nil |
|||
} |
|||
self.smallestScalar = smallScalars.first!.value |
|||
self.largestScalar = largeScalars.first!.value |
|||
self.sizeAlphabet = (largestScalar - smallestScalar) + 1 |
|||
let scalars = convertToUnicodeScalars(str: key, minChar: smallestScalar, maxChar: largestScalar) |
|||
guard !scalars.isEmpty else { |
|||
return nil |
|||
} |
|||
self.keyScalars = scalars |
|||
} |
|||
public func decrypt(_ str: String) -> String? { |
|||
let txtBytes = convertToUnicodeScalars(str: str, minChar: smallestScalar, maxChar: largestScalar) |
|||
guard !txtBytes.isEmpty else { |
|||
return nil |
|||
} |
|||
var res = "" |
|||
for (i, c) in txtBytes.enumerated() where c >= smallestScalar && c <= largestScalar { |
|||
guard let char = |
|||
UnicodeScalar((c &+ sizeAlphabet &- keyScalars[i % keyScalars.count]) % sizeAlphabet &+ smallestScalar) |
|||
else { |
|||
return nil |
|||
} |
|||
res += String(char) |
|||
} |
|||
return res |
|||
} |
|||
public func encrypt(_ str: String) -> String? { |
|||
let txtBytes = convertToUnicodeScalars(str: str, minChar: smallestScalar, maxChar: largestScalar) |
|||
guard !txtBytes.isEmpty else { |
|||
return nil |
|||
} |
|||
var res = "" |
|||
for (i, c) in txtBytes.enumerated() where c >= smallestScalar && c <= largestScalar { |
|||
guard let char = |
|||
UnicodeScalar((c &+ keyScalars[i % keyScalars.count] &- 2 &* smallestScalar) % sizeAlphabet &+ smallestScalar) |
|||
else { |
|||
return nil |
|||
} |
|||
res += String(char) |
|||
} |
|||
return res |
|||
} |
|||
} |
|||
let text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"; |
|||
let key = "VIGENERECIPHER"; |
|||
let cipher = Vigenere(key: key)! |
|||
print("Key: \(key)") |
|||
print("Plain Text: \(text)") |
|||
let encoded = cipher.encrypt(text.uppercased())! |
|||
print("Cipher Text: \(encoded)") |
|||
let decoded = cipher.decrypt(encoded)! |
|||
print("Decoded: \(decoded)") |
|||
print("\nLarger set:") |
|||
let key2 = "Vigenère cipher" |
|||
let text2 = "This is a ünicode string 😃" |
|||
let cipher2 = Vigenere(key: key2, smallestCharacter: " ", largestCharacter: "🛹")! |
|||
print("Key: \(key2)") |
|||
print("Plain Text: \(text2)") |
|||
let encoded2 = cipher2.encrypt(text2)! |
|||
print("Cipher Text: \(encoded2)") |
|||
let decoded2 = cipher2.decrypt(encoded2)! |
|||
print("Decoded: \(decoded2)")</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Key: VIGENERECIPHER |
|||
Plain Text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
Cipher Text: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
Decoded: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
Larger set: |
|||
Key: Vigenère cipher |
|||
Plain Text: This is a ünicode string 😃 |
|||
Cipher Text: �±°¸nıÅeacŅ¾±¨Á�®g¸Âĺ»³gc🙌 |
|||
Decoded: This is a ünicode string 😃</pre> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{trans|C++}} |
{{trans|C++}} |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.6 |
||
oo::class create Vigenere { |
oo::class create Vigenere { |
||
Line 2,372: | Line 4,253: | ||
return $out |
return $out |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Demonstrating: |
Demonstrating: |
||
< |
<syntaxhighlight lang="tcl">set cypher [Vigenere new "Vigenere Cipher"] |
||
set original "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
set original "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
||
set encrypted [$cypher encrypt $original] |
set encrypted [$cypher encrypt $original] |
||
Line 2,380: | Line 4,261: | ||
puts $original |
puts $original |
||
puts "Encrypted: $encrypted" |
puts "Encrypted: $encrypted" |
||
puts "Decrypted: $decrypted"</ |
puts "Decrypted: $decrypted"</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
||
Line 2,390: | Line 4,271: | ||
=={{header|TXR}}== |
=={{header|TXR}}== |
||
< |
<syntaxhighlight lang="txr">@(next :args) |
||
@(do |
@(do |
||
(defun vig-op (plus-or-minus) |
|||
(defun letter-mod26-op (func) ;; add or subtract capital letters modulo 26 |
|||
( |
(op + #\A [mod [plus-or-minus (- @1 #\A) (- @2 #\A)] 26])) |
||
(defun vig (msg key encrypt) |
(defun vig (msg key encrypt) |
||
(mapcar (vig-op [if encrypt + -]) msg (repeat key)))) |
|||
(list-str msg) |
|||
(repeat (list-str key))) ""))) |
|||
@(coll)@{key /[A-Za-z]/}@(end) |
@(coll)@{key /[A-Za-z]/}@(end) |
||
@(coll)@{msg /[A-Za-z]/}@(end) |
@(coll)@{msg /[A-Za-z]/}@(end) |
||
Line 2,413: | Line 4,293: | ||
dec: @decoded |
dec: @decoded |
||
check: @check |
check: @check |
||
@(end)</ |
@(end)</syntaxhighlight> |
||
Here, the TXR pattern language is used to scan letters out of two arguments, |
Here, the TXR pattern language is used to scan letters out of two arguments, |
||
and convert them to upper case. |
|||
The embedded TXR Lisp dialect handles the Vigenère logic, |
|||
in just a few lines of code. |
|||
Lisp programmers may do a "double take" at what is going on here: yes <code>mapcar</code> can operate on strings and return strings in TXR Lisp. <code>(repeat key)</code> produces an infinite lazy list; but that's okay because <code>mapcar</code> stops after the shortest input runs out of items. |
|||
The Vigenère substitution is driven by good old Lisp <code>mapcar</code> which works over the data represented as lists of characters (provided by applying the <code>list-str</code> function to the string inputs). |
|||
Run: |
|||
Now <code>mapcar</code> walks lists in parallel, stopping at the end of the shortest list. This traditional behavior of <code>mapcar</code> turns out to be a very good idea when you introduce infinite lazy lists into the mix. Infinite lists are longer than concrete lists and so mapcar keeps going until the shortest concrete list runs out. |
|||
<pre>$ txr vigenere.txr 'vigenere cipher' 'Beware the Jabberwock... The jaws that... the claws that catch!' |
|||
We can represent the text to be enciphered or deciphered as a concrete list of the letters, and the Vigenère key as an infinite lazy list, giving us a key pad which consists of an infinite number of repetitions of the key. Such a list is produced by TXR Lisp's <code>repeat</code> operator, which takes a list and makes a lazy list out of repetitions of that list. |
|||
Then <code>mapcar</code> will zip the text and the infinite key pad two together, through the addition or subtraction operation. |
|||
TXR Lisp's <code>+</code> and <code>-</code> operators are generic over characters. An integer may be added to a character to produce a displacement through the code space to get to another character. When a character is subtracted from another, the result is an integer which is the difference between their codes. |
|||
<pre>$ ./txr vigenere.txr 'vigenere cipher' 'Beware the Jabberwock... The jaws that... the claws that catch!' |
|||
text: BEWARETHEJABBERWOCKTHEJAWSTHATTHECLAWSTHATCATCH |
text: BEWARETHEJABBERWOCKTHEJAWSTHATTHECLAWSTHATCATCH |
||
key: VIGENERECIPHER |
key: VIGENERECIPHER |
||
Line 2,433: | Line 4,310: | ||
dec: GWQWEACDCBLUXNWOIYXPQAHSHLPQFLNDRYUWUKEAWCHSNYU |
dec: GWQWEACDCBLUXNWOIYXPQAHSHLPQFLNDRYUWUKEAWCHSNYU |
||
check: BEWARETHEJABBERWOCKTHEJAWSTHATTHECLAWSTHATCATCH</pre> |
check: BEWARETHEJABBERWOCKTHEJAWSTHATTHECLAWSTHATCATCH</pre> |
||
=={{header|TypeScript}}== |
|||
<syntaxhighlight lang="javascript">class Vigenere { |
|||
key: string |
|||
/** Create new cipher based on key */ |
|||
constructor(key: string) { |
|||
this.key = Vigenere.formatText(key) |
|||
} |
|||
/** Enrypt a given text using key */ |
|||
encrypt(plainText: string): string { |
|||
return Array.prototype.map.call(Vigenere.formatText(plainText), (letter: string, index: number): string => { |
|||
return String.fromCharCode((letter.charCodeAt(0) + this.key.charCodeAt(index % this.key.length) - 130) % 26 + 65) |
|||
}).join('') |
|||
} |
|||
/** Decrypt ciphertext based on key */ |
|||
decrypt(cipherText: string): string { |
|||
return Array.prototype.map.call(Vigenere.formatText(cipherText), (letter: string, index: number): string => { |
|||
return String.fromCharCode((letter.charCodeAt(0) - this.key.charCodeAt(index % this.key.length) + 26) % 26 + 65) |
|||
}).join('') |
|||
} |
|||
/** Converts to uppercase and removes non characters */ |
|||
private static formatText(text: string): string { |
|||
return text.toUpperCase().replace(/[^A-Z]/g, "") |
|||
} |
|||
} |
|||
/** Example usage */ |
|||
(() => { |
|||
let original: string = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book." |
|||
console.log(`Original: ${original}`) |
|||
let vig: Vigenere = new Vigenere("vigenere") |
|||
let encoded: string = vig.encrypt(original) |
|||
console.log(`After encryption: ${encoded}`) |
|||
let back: string = vig.decrypt(encoded) |
|||
console.log(`After decryption: ${back}`) |
|||
})() |
|||
</syntaxhighlight> |
|||
=={{header|VBA}}== |
|||
<syntaxhighlight lang="vb">Option Explicit |
|||
Sub test() |
|||
Dim Encryp As String |
|||
Encryp = Vigenere("Beware the Jabberwock, my son! The jaws that bite, the claws that catch!", "vigenerecipher", True) |
|||
Debug.Print "Encrypt:= """ & Encryp & """" |
|||
Debug.Print "Decrypt:= """ & Vigenere(Encryp, "vigenerecipher", False) & """" |
|||
End Sub |
|||
Private Function Vigenere(sWord As String, sKey As String, Enc As Boolean) As String |
|||
Dim bw() As Byte, bk() As Byte, i As Long, c As Long |
|||
Const sW As String = "ÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ" |
|||
Const sWo As String = "AAAAACEEEEIIIINOOOOOUUUUY" |
|||
Const A As Long = 65 |
|||
Const N As Long = 26 |
|||
c = Len(sKey) |
|||
i = Len(sWord) |
|||
sKey = Left(IIf(c < i, StrRept(sKey, (i / c) + 1), sKey), i) |
|||
sKey = StrConv(sKey, vbUpperCase) 'Upper case |
|||
sWord = StrConv(sWord, vbUpperCase) |
|||
sKey = StrReplace(sKey, sW, sWo) 'Replace accented characters |
|||
sWord = StrReplace(sWord, sW, sWo) |
|||
sKey = RemoveChars(sKey) 'Remove characters (numerics, spaces, comas, ...) |
|||
sWord = RemoveChars(sWord) |
|||
bk = CharToAscii(sKey) 'To work with Bytes instead of String |
|||
bw = CharToAscii(sWord) |
|||
For i = LBound(bw) To UBound(bw) |
|||
Vigenere = Vigenere & Chr((IIf(Enc, ((bw(i) - A) + (bk(i) - A)), ((bw(i) - A) - (bk(i) - A)) + N) Mod N) + A) |
|||
Next i |
|||
End Function |
|||
Private Function StrRept(s As String, N As Long) As String |
|||
Dim j As Long, c As String |
|||
For j = 1 To N |
|||
c = c & s |
|||
Next |
|||
StrRept = c |
|||
End Function |
|||
Private Function StrReplace(s As String, What As String, By As String) As String |
|||
Dim t() As String, u() As String, i As Long |
|||
t = SplitString(What) |
|||
u = SplitString(By) |
|||
StrReplace = s |
|||
For i = LBound(t) To UBound(t) |
|||
StrReplace = Replace(StrReplace, t(i), u(i)) |
|||
Next i |
|||
End Function |
|||
Private Function SplitString(s As String) As String() |
|||
SplitString = Split(StrConv(s, vbUnicode), Chr(0)) |
|||
End Function |
|||
Private Function RemoveChars(str As String) As String |
|||
Dim b() As Byte, i As Long |
|||
b = CharToAscii(str) |
|||
For i = LBound(b) To UBound(b) |
|||
If b(i) >= 65 And b(i) <= 90 Then RemoveChars = RemoveChars & Chr(b(i)) |
|||
Next i |
|||
End Function |
|||
Private Function CharToAscii(s As String) As Byte() |
|||
CharToAscii = StrConv(s, vbFromUnicode) |
|||
End Function</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>Encrypt:= "WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY" |
|||
Decrypt:= "BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH"</pre> |
|||
=={{header|VBScript}}== |
|||
{{trans|Liberty BASIC}} |
|||
<syntaxhighlight lang="vb"> |
|||
Function Encrypt(text,key) |
|||
text = OnlyCaps(text) |
|||
key = OnlyCaps(key) |
|||
j = 1 |
|||
For i = 1 To Len(text) |
|||
ms = Mid(text,i,1) |
|||
m = Asc(ms) - Asc("A") |
|||
ks = Mid(key,j,1) |
|||
k = Asc(ks) - Asc("A") |
|||
j = (j Mod Len(key)) + 1 |
|||
c = (m + k) Mod 26 |
|||
c = Chr(Asc("A")+c) |
|||
Encrypt = Encrypt & c |
|||
Next |
|||
End Function |
|||
Function Decrypt(text,key) |
|||
key = OnlyCaps(key) |
|||
j = 1 |
|||
For i = 1 To Len(text) |
|||
ms = Mid(text,i,1) |
|||
m = Asc(ms) - Asc("A") |
|||
ks = Mid(key,j,1) |
|||
k = Asc(ks) - Asc("A") |
|||
j = (j Mod Len(key)) + 1 |
|||
c = (m - k + 26) Mod 26 |
|||
c = Chr(Asc("A")+c) |
|||
Decrypt = Decrypt & c |
|||
Next |
|||
End Function |
|||
Function OnlyCaps(s) |
|||
For i = 1 To Len(s) |
|||
char = UCase(Mid(s,i,1)) |
|||
If Asc(char) >= 65 And Asc(char) <= 90 Then |
|||
OnlyCaps = OnlyCaps & char |
|||
End If |
|||
Next |
|||
End Function |
|||
'testing the functions |
|||
orig_text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
orig_key = "vigenerecipher" |
|||
WScript.StdOut.WriteLine "Original: " & orig_text |
|||
WScript.StdOut.WriteLine "Key: " & orig_key |
|||
WScript.StdOut.WriteLine "Encrypted: " & Encrypt(orig_text,orig_key) |
|||
WScript.StdOut.WriteLine "Decrypted: " & Decrypt(Encrypt(orig_text,orig_key),orig_key) |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
Original: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
Key: vigenerecipher |
|||
Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
</pre> |
|||
An alternate implementation using RegExp to filter the input |
|||
<syntaxhighlight lang="vb"> |
|||
'vigenere cypher |
|||
option explicit |
|||
const asca =65 'ascii(a) |
|||
function filter(s) |
|||
with new regexp |
|||
.pattern="[^A-Z]" |
|||
.global=1 |
|||
filter=.replace(ucase(s),"") |
|||
end with |
|||
end function |
|||
function vigenere (s,k,sign) |
|||
dim s1,i,a,b |
|||
for i=0 to len(s)-1 |
|||
a=asc(mid(s,i+1,1))-asca |
|||
b=sign * (asc(mid(k,(i mod len(k))+1,1))-asca) |
|||
s1=s1 & chr(((a+b+26) mod 26) +asca) |
|||
next |
|||
vigenere=s1 |
|||
end function |
|||
function encrypt(s,k): encrypt=vigenere(s,k,1) :end function |
|||
function decrypt(s,k): decrypt=vigenere(s,k,-1) :end function |
|||
'test-------------------------- |
|||
dim plaintext,filtered,key,encoded |
|||
key="VIGENERECYPHER" |
|||
plaintext = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
filtered= filter(plaintext) |
|||
wscript.echo filtered |
|||
encoded=encrypt(filtered,key) |
|||
wscript.echo encoded |
|||
wscript.echo decrypt(encoded,key) |
|||
</syntaxhighlight> |
|||
=={{header|Vedit macro language}}== |
=={{header|Vedit macro language}}== |
||
Encrypts and then decrypts one line of text on current edit buffer |
Encrypts and then decrypts one line of text on current edit buffer, |
||
starting from cursor location. |
|||
<lang vedit>Get_Input(10, "Key: ", STATLINE+NOCR) // @10 = key |
|||
The user enters the keyword (upper or lower case). |
|||
<syntaxhighlight lang="vedit">Get_Input(10, "Key: ", STATLINE+NOCR) // @10 = key |
|||
Reg_Copy_Block(11, Cur_Pos, EOL_Pos) // @11 = copy of original text |
Reg_Copy_Block(11, Cur_Pos, EOL_Pos) // @11 = copy of original text |
||
EOL Ins_Newline |
EOL Ins_Newline |
||
Line 2,483: | Line 4,582: | ||
} |
} |
||
Num_Pop(6,9) |
Num_Pop(6,9) |
||
Return </ |
Return </syntaxhighlight> |
||
{{out}} |
|||
Sample output: |
|||
<pre> |
<pre> |
||
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
||
Line 2,491: | Line 4,590: | ||
Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
||
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
||
</pre> |
|||
=={{header|V (Vlang)}}== |
|||
<syntaxhighlight lang="v (vlang)"> |
|||
const |
|||
( |
|||
key = "VIGENERECIPHER" |
|||
text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
) |
|||
fn main() { |
|||
encoded := vigenere(text, key, true) |
|||
println(encoded) |
|||
decoded := vigenere(encoded, key, false) |
|||
println(decoded) |
|||
} |
|||
fn vigenere(str string, key string, encrypt bool) string { |
|||
mut txt :='' |
|||
mut chr_arr := []u8{} |
|||
mut kidx, mut cidx := 0, 0 |
|||
if encrypt == true {txt = str.to_upper()} |
|||
else {txt = str} |
|||
for chr in txt { |
|||
if (chr > 64 && chr < 91) == false {continue} |
|||
if encrypt == true {cidx = (chr + key[kidx] - 130) % 26} |
|||
else {cidx = (chr - key[kidx] + 26) % 26} |
|||
chr_arr << u8(cidx + 65) |
|||
kidx = (kidx + 1) % key.len |
|||
} |
|||
return chr_arr.bytestr() |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
</pre> |
|||
=={{header|Wren}}== |
|||
{{trans|Kotlin}} |
|||
{{libheader|Wren-str}} |
|||
<syntaxhighlight lang="wren">import "./str" for Char, Str |
|||
var vigenere = Fn.new { |text, key, encrypt| |
|||
var t = encrypt ? Str.upper(text) : text |
|||
var sb = "" |
|||
var ki = 0 |
|||
for (c in t) { |
|||
if (Char.isAsciiUpper(c)) { |
|||
var ci = encrypt ? (c.bytes[0] + key[ki].bytes[0] - 130) % 26 : |
|||
(c.bytes[0] - key[ki].bytes[0] + 26) % 26 |
|||
sb = sb + Char.fromCode(ci + 65) |
|||
ki = (ki + 1) % key.count |
|||
} |
|||
} |
|||
return sb |
|||
} |
|||
var key = "VIGENERECIPHER" |
|||
var text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" |
|||
var encoded = vigenere.call(text, key, true) |
|||
System.print(encoded) |
|||
var decoded = vigenere.call(encoded, key, false) |
|||
System.print(decoded)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
</pre> |
</pre> |
||
Line 2,497: | Line 4,667: | ||
Usage: vigenere KEYWORD <infile.txt >outfile.xxx |
Usage: vigenere KEYWORD <infile.txt >outfile.xxx |
||
< |
<syntaxhighlight lang="xpl0">code ChIn=7, ChOut=8; |
||
int Neg, C, Len, I, Key; |
int Neg, C, Len, I, Key; |
||
char KeyWord(80); |
char KeyWord(80); |
||
Line 2,517: | Line 4,687: | ||
until C=$1A; \EOF |
until C=$1A; \EOF |
||
ChOut(0, $1A); \encrypted file must end with EOF otherwise the decode will hang |
ChOut(0, $1A); \encrypted file must end with EOF otherwise the decode will hang |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
|||
Example output: |
|||
<pre> |
<pre> |
||
KEYWORD = ACE |
KEYWORD = ACE |
||
Line 2,528: | Line 4,698: | ||
</pre> |
</pre> |
||
=={{header|Zig}}== |
|||
{{omit from|GUISS|An application would be needed to be installed that could do this}} |
|||
{{ |
{{works with|Zig|0.11.0}} |
||
<syntaxhighlight lang="zig"> |
|||
const std = @import("std"); |
|||
const Allocator = std.mem.Allocator; |
|||
</syntaxhighlight><syntaxhighlight lang="zig"> |
|||
const Vigenere = enum { |
|||
encode, |
|||
decode, |
|||
}; |
|||
</syntaxhighlight><syntaxhighlight lang="zig"> |
|||
pub fn main() anyerror!void { |
|||
// ------------------------------------------ allocator |
|||
var gpa = std.heap.GeneralPurposeAllocator(.{}){}; |
|||
defer { |
|||
const ok = gpa.deinit(); |
|||
std.debug.assert(ok == .ok); |
|||
} |
|||
const allocator = gpa.allocator(); |
|||
// --------------------------------------------- stdout |
|||
const stdout = std.io.getStdOut().writer(); |
|||
// ---------------------------------------------------- |
|||
const key = "VIGENERECIPHER"; |
|||
const text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"; |
|||
const encoded = try vigenere(allocator, text, key, .encode); |
|||
defer allocator.free(encoded); |
|||
try stdout.print("{s}\n", .{encoded}); |
|||
const decoded = try vigenere(allocator, encoded, key, .decode); |
|||
defer allocator.free(decoded); |
|||
try stdout.print("{s}\n", .{decoded}); |
|||
} |
|||
</syntaxhighlight><syntaxhighlight lang="zig"> |
|||
/// Caller owns the returned slice memory. |
|||
fn vigenere(allocator: Allocator, text: []const u8, key: []const u8, mode: Vigenere) Allocator.Error![]u8 { |
|||
var dynamic_string = std.ArrayList(u8).init(allocator); |
|||
var key_index: usize = 0; |
|||
for (text) |letter| { |
|||
const c = if (std.ascii.isLower(letter)) std.ascii.toUpper(letter) else letter; |
|||
if (std.ascii.isUpper(c)) { |
|||
const k = key[key_index]; |
|||
const n = switch (mode) { |
|||
.encode => ((c - 'A') + (k - 'A')), |
|||
.decode => 26 + c - k, |
|||
}; |
|||
try dynamic_string.append(n % 26 + 'A'); // A-Z |
|||
key_index += 1; |
|||
key_index %= key.len; |
|||
} |
|||
} |
|||
return dynamic_string.toOwnedSlice(); |
|||
} |
|||
</syntaxhighlight>{{out}} |
|||
<pre>WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH</pre> |
|||
=={{header|zkl}}== |
|||
{{trans|C}} |
|||
<syntaxhighlight lang="zkl">fcn encipher(src,key,is_encode){ |
|||
upperCase:=["A".."Z"].pump(String); |
|||
src=src.toUpper().inCommon(upperCase); // only uppercase |
|||
key=key.toUpper().inCommon(upperCase).pump(List,"toAsc"); |
|||
const A="A".toAsc(); |
|||
klen:=Walker.cycle(key.len()); // 0,1,2,3,..,keyLen-1,0,1,2,3, ... |
|||
src.pump(String,'wrap(c){ i:=klen.next(); c=c.toAsc(); |
|||
(A + ( if(is_encode) c - A + key[i] - A; |
|||
else c - key[i] + 26 ) % 26).toChar() |
|||
}); |
|||
}</syntaxhighlight> |
|||
<syntaxhighlight lang="zkl">str := "Beware the Jabberwock, my son! The jaws that bite, " |
|||
"the claws that catch!"; |
|||
key := "Vigenere Cipher"; |
|||
println("Text: ", str); |
|||
println("key: ", key); |
|||
cod := encipher(str, key, True); println("Code: ", cod); |
|||
dec := encipher(cod, key, False); println("Back: ", dec);</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! |
|||
key: Vigenere Cipher |
|||
Code: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY |
|||
Back: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH |
|||
</pre> |
Latest revision as of 11:04, 16 February 2024
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Implement a Vigenère cypher, both encryption and decryption.
The program should handle keys and text of unequal length,
and should capitalize everything and discard non-alphabetic characters.
(If your program handles non-alphabetic characters in another way,
make a note of it.)
- Related tasks
11l
F encrypt(key, text)
V out = ‘’
V j = 0
L(c) text
I !c.is_alpha()
L.continue
out ‘’= Char(code' (c.uppercase().code + key[j].code - 2 * ‘A’.code) % 26 + ‘A’.code)
j = (j + 1) % key.len
R out
F decrypt(key, text)
V out = ‘’
V j = 0
L(c) text
I !c.is_alpha()
L.continue
out ‘’= Char(code' (c.code - key[j].code + 26) % 26 + ‘A’.code)
j = (j + 1) % key.len
R out
V key = ‘VIGENERECIPHER’
V original = ‘Beware the Jabberwock, my son! The jaws that bite, the claws that catch!’
V encrypted = encrypt(key, original)
V decrypted = decrypt(key, encrypted)
print(original)
print(‘Encrypted: ’encrypted)
print(‘Decrypted: ’decrypted)
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Action!
PROC Fix(CHAR ARRAY in,fixed)
INT i
CHAR c
fixed(0)=0
FOR i=1 TO in(0)
DO
c=in(i)
IF c>='a AND c<='z THEN
c==-('a-'A)
FI
IF c>='A AND c<='Z THEN
fixed(0)==+1
fixed(fixed(0))=c
FI
OD
RETURN
PROC Process(CHAR ARRAY in,key,out INT dir)
CHAR ARRAY inFixed(256),keyFixed(256)
INT keyI,tmp,i
CHAR c
out(0)=0
Fix(in,inFixed)
Fix(key,keyFixed)
IF inFixed(0)=0 OR keyFixed(0)=0 THEN
RETURN
FI
keyI=1
FOR i=1 TO inFixed(0)
DO
c=inFixed(i)
tmp=c-'A+dir*(keyFixed(keyI)-'A)
IF tmp<0 THEN
tmp==+26
FI
out(0)==+1
out(out(0))='A+tmp MOD 26
keyI==+1
IF keyI>keyFixed(0) THEN
keyI=1
FI
OD
RETURN
PROC Encrypt(CHAR ARRAY in,key,out)
Process(in,key,out,1)
RETURN
PROC Decrypt(CHAR ARRAY in,key,out)
Process(in,key,out,-1)
RETURN
PROC Test(CHAR ARRAY in,key)
CHAR ARRAY enc(256),dec(256)
PrintE("Original:") PrintE(in)
Encrypt(in,key,enc)
PrintF("Encrypted key=%S:%E",key) PrintE(enc)
Decrypt(enc,key,dec)
PrintF("Decrypted key=%S:%E",key) PrintE(dec)
PutE()
RETURN
PROC Main()
Test("Attack at dawn!","LEMONLEMONLE")
Test("Crypto is short for cryptography.","ABCDABCDABCDABCDABCDABCDABCD")
RETURN
- Output:
Screenshot from Atari 8-bit computer
Original: Attack at dawn! Encrypted key=LEMONLEMONLE: LXFOPVEFRNHR Decrypted key=LEMONLEMONLE: ATTACKATDAWN Original: Crypto is short for cryptography. Encrypted key=ABCDABCDABCDABCDABCDABCDABCD: CSASTPKVSIQUTGQUCSASTPIUAQJB Decrypted key=ABCDABCDABCDABCDABCDABCDABCD: CRYPTOISSHORTFORCRYPTOGRAPHY
Ada
WITH Ada.Text_IO, Ada.Characters.Handling;
USE Ada.Text_IO, Ada.Characters.Handling;
PROCEDURE Main IS
SUBTYPE Alpha IS Character RANGE 'A' .. 'Z';
TYPE Ring IS MOD (Alpha'Range_length);
TYPE Seq IS ARRAY (Integer RANGE <>) OF Ring;
FUNCTION "+" (S, Key : Seq) RETURN Seq IS
R : Seq (S'Range);
BEGIN
FOR I IN R'Range LOOP
R (I) := S (I) + Key (Key'First + (I - R'First) MOD Key'Length);
END LOOP;
RETURN R;
END "+";
FUNCTION "-" (S : Seq) RETURN Seq IS
R : Seq (S'Range);
BEGIN
FOR I IN R'Range LOOP
R (I) := - S (I);
END LOOP;
RETURN R;
END "-";
FUNCTION To_Seq (S : String) RETURN Seq IS
R : Seq (S'Range);
I : Integer := R'First;
BEGIN
FOR C OF To_Upper (S) LOOP
IF C IN Alpha THEN
R (I) := Ring'Mod (Alpha'Pos (C) - Alpha'Pos (Alpha'First));
I := I + 1;
END IF;
END LOOP;
RETURN R (R'First .. I - 1);
END To_Seq;
FUNCTION To_String (S : Seq ) RETURN String IS
R : String (S'Range);
BEGIN
FOR I IN R'Range LOOP
R (I) := Alpha'Val ( Integer (S (I)) + Alpha'Pos (Alpha'First));
END LOOP;
RETURN R;
END To_String;
Input : Seq := To_Seq (Get_Line);
Key : Seq := To_Seq (Get_Line);
Crypt : Seq := Input + Key;
BEGIN
Put_Line ("Encrypted: " & To_String (Crypt));
Put_Line ("Decrypted: " & To_String (Crypt + (-Key)));
END Main;
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! VIGENERECIPHER Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
ALGOL 68
Note: This specimen retains the original C++ coding style.
STRING key := "";
PROC vigenere cipher = (REF STRING key)VOID:
(
FOR i FROM LWB key TO UPB key DO
IF key[i] >= "A" AND key[i] <= "Z" THEN
key +:= key[i] FI;
IF key[i] >= "a" AND key[i] <= "z" THEN
key +:= REPR(ABS key[i] + ABS"A" - ABS"a") FI
OD
);
PROC encrypt = (STRING text)STRING:
(
STRING out := "";
INT j := LWB text;
FOR i FROM LWB text TO UPB text DO
CHAR c := text[i];
IF c >= "a" AND c <= "z" THEN
c := REPR(ABS c + (ABS"A" - ABS"a")) FI;
IF c >= "A" AND c <= "Z" THEN
out +:= REPR((ABS c + ABS key[j] - 2*ABS"A") MOD 26 + ABS"A");
j := j MOD UPB key + 1
FI
OD;
out
);
PROC decrypt = (STRING text)STRING:
(
STRING out;
INT j := LWB text;
FOR i FROM LWB text TO UPB text DO
CHAR c := text[i];
IF c >= "a" AND c <= "z" THEN
c := REPR(ABS c + (ABS"A" - ABS"a")) FI;
IF c >= "A" AND c <= "Z" THEN
out +:= REPR((ABS c - ABS key[j] + 26) MOD 26 + ABS"A");
j := j MOD UPB key + 1
FI
OD;
out
);
main:
(
vigenere cipher(key:="VIGENERECIPHER");
STRING original := "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
STRING encrypted := encrypt(original);
STRING decrypted := decrypt(encrypted);
print((original, new line));
print(("Encrypted: ", encrypted, new line));
print(("Decrypted: ", decrypted, new line))
)
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Applesoft BASIC
Lines 340,350,430,440
could probably been put into some DEF FN, but it would probably have made it harder to read. The maximum length for a string in AppleSoft BASIC is 255 characters.
I have not used the DEF FN MOD(A) function in line 450
on purpose, as I still would have had to correct for a possible negative value.
100 :
110 REM VIGENERE CIPHER
120 :
200 REM SET-UP
210 K$ = "LEMON": PRINT "KEY: "; K$
220 PT$ = "ATTACK AT DAWN": PRINT "PLAIN TEXT: ";PT$
230 DEF FN MOD(A) = A - INT (A / 26) * 26
300 REM ENCODING
310 K = 1
320 FOR I = 1 TO LEN (PT$)
330 IF ASC ( MID$ (PT$,I,1)) < 65
OR ASC ( MID$ (PT$,I,1)) > 90 THEN NEXT I
340 TV = ASC ( MID$ (PT$,I,1)) - 65
350 KV = ASC ( MID$ (K$,K,1)) - 65
360 CT$ = CT$ + CHR$ ( FN MOD(TV + KV) + 65)
370 K = K + 1: IF K > LEN (K$) THEN K = 1
380 NEXT I
390 PRINT "CIPHER TEXT: ";CT$
400 REM DECODING
410 K = 1
420 FOR I = 1 TO LEN (CT$)
430 TV = ASC ( MID$ (CT$,I,1)) - 65
440 KV = ASC ( MID$ (K$,K,1)) - 65
450 T = TV - KV: IF T < 0 THEN T = T + 26
460 DT$ = DT$ + CHR$ (T + 65)
470 K = K + 1: IF K > LEN (K$) THEN K = 1
480 NEXT I
490 PRINT "DECRYPTED TEXT: ";DT$
- Output:
KEY: LEMON PLAIN TEXT: ATTACK AT DAWN CIPHER TEXT: LXFOPVEFRNHR DECRYPTED TEXT: ATTACKATDAWN
Arturo
Letters: append `A`..`Z` `a`..`z`
encrypt: function [msg, key][
pos: 0
result: new ""
loop msg 'c ->
if in? c Letters [
'result ++ to :char (((to :integer key\[pos]) + to :integer upper c) % 26) + to :integer `A`
pos: (pos + 1) % size key
]
return result
]
decrypt: function [msg, key][
pos: 0
result: new ""
loop msg 'c [
'result ++ to :char ((26 + (to :integer c) - to :integer key\[pos]) % 26) + to :integer `A`
pos: (pos + 1) % size key
]
return result
]
text: "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
key: "VIGENERECIPHER"
encr: encrypt text key
decr: decrypt encr key
print text
print encr
print decr
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
AutoHotkey
Key = VIGENERECIPHER
Text= Beware the Jabberwock, my son! The jaws that bite, the claws that catch!
out := "Input =" text "`nkey =" key "`nCiphertext =" (c := VigenereCipher(Text, Key)) "`nDecrypted =" VigenereDecipher(c, key)
MsgBox % clipboard := out
VigenereCipher(Text, Key){
StringUpper, Text, Text
Text := RegExReplace(Text, "[^A-Z]")
Loop Parse, Text
{
a := Asc(A_LoopField) - Asc("A")
b := Asc(SubStr(Key, 1+Mod(A_Index-1, StrLen(Key)), 1)) - Asc("A")
out .= Chr(Mod(a+b,26)+Asc("A"))
}
return out
}
VigenereDecipher(Text, key){
Loop Parse, key
decoderKey .= Chr(26-(Asc(A_LoopField)-65)+65)
return VigenereCipher(Text, decoderKey)
}
- Output:
Input =Beware the Jabberwock, my son! The jaws that bite, the claws that catch! key =VIGENERECIPHER Ciphertext =WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted =BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
BASIC256
function Filtrar(cadorigen)
filtrado = ""
for i = 1 to length(cadorigen)
letra = upper(mid(cadorigen, i, 1))
if instr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", letra) then filtrado += letra
next i
return filtrado
end function
function Encriptar(texto, llave)
texto = Filtrar(texto)
cifrado = ""
j = 1
for i = 1 to length(texto)
mSS = mid(texto, i, 1)
m = asc(mSS) - asc("A")
kSS = mid(llave, j, 1)
k = asc(kSS) - asc("A")
j = (j mod length(llave)) + 1
c = (m + k) mod 26
letra = chr(asc("A") + c)
cifrado += letra
next i
return cifrado
end function
function DesEncriptar(texto, llave)
descifrado = ""
j = 1
for i = 1 to length(texto)
mSS = mid(texto, i, 1)
m = asc(mSS) - asc("A")
kSS = mid(llave, j, 1)
k = asc(kSS) - asc("A")
j = (j mod length(llave)) + 1
c = (m - k + 26) mod 26
letra = chr(asc("A")+c)
descifrado += letra
next i
return descifrado
end function
llave = Filtrar("vigenerecipher")
cadorigen = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
print cadorigen
print llave
cadcifrada = Encriptar(cadorigen, llave)
print " Cifrado: "; cadcifrada
print "Descifrado: "; DesEncriptar(cadcifrada, llave)
end
- Output:
Igual que la entrada de FreeBASIC.
BBC BASIC
key$ = "LEMON"
plaintext$ = "ATTACK AT DAWN"
ciphertext$ = FNencrypt(plaintext$, key$)
PRINT "Key = """ key$ """"
PRINT "Plaintext = """ plaintext$ """"
PRINT "Ciphertext = """ ciphertext$ """"
PRINT "Decrypted = """ FNdecrypt(ciphertext$, key$) """"
END
DEF FNencrypt(plain$, key$)
LOCAL i%, k%, n%, o$
plain$ = FNupper(plain$)
key$ = FNupper(key$)
FOR i% = 1 TO LEN(plain$)
n% = ASCMID$(plain$, i%)
IF n% >= 65 IF n% <= 90 THEN
o$ += CHR$(65 + (n% + ASCMID$(key$, k%+1)) MOD 26)
k% = (k% + 1) MOD LEN(key$)
ENDIF
NEXT
= o$
DEF FNdecrypt(cipher$, key$)
LOCAL i%, k%, n%, o$
cipher$ = FNupper(cipher$)
key$ = FNupper(key$)
FOR i% = 1 TO LEN(cipher$)
n% = ASCMID$(cipher$, i%)
o$ += CHR$(65 + (n% + 26 - ASCMID$(key$, k%+1)) MOD 26)
k% = (k% + 1) MOD LEN(key$)
NEXT
= o$
DEF FNupper(A$)
LOCAL A%,C%
FOR A% = 1 TO LEN(A$)
C% = ASCMID$(A$,A%)
IF C% >= 97 IF C% <= 122 MID$(A$,A%,1) = CHR$(C%-32)
NEXT
= A$
- Output:
Key = "LEMON" Plaintext = "ATTACK AT DAWN" Ciphertext = "LXFOPVEFRNHR" Decrypted = "ATTACKATDAWN"
Befunge
The text to encrypt is read from stdin. The key is the string literal at the start of the program.
"VIGENERECIPHER">>>>1\:!v>"A"-\:00p0v
>>!#:0#-0#1g#,*#<+:v:-1$_^#!:\+1g00p<
\"{"\v>9+2*%"A"+^>$>~>:48*\`#@_::"`"`
*84*`<^4+"4"+g0\_^#!+`*55\`\0::-"A"-*
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY
The decrypter is essentially identical, except for a change of sign on the last line.
"VIGENERECIPHER">>>>1\:!v>"A"-\:00p0v
>>!#:0#-0#1g#,*#<+:v:-1$_^#!:\+1g00p<
\"{"\v>9+2*%"A"+^>$>~>:48*\`#@_::"`"`
*84*`<^4+"4"-g0\_^#!+`*55\`\0::-"A"-*
- Output:
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
C
This program skips non-alphabetical characters, preserves case, and when run with the -d
command line flag, decrypts the message rather than encrypting.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
#include <getopt.h>
#define NUMLETTERS 26
#define BUFSIZE 4096
char *get_input(void);
int main(int argc, char *argv[])
{
char const usage[] = "Usage: vinigere [-d] key";
char sign = 1;
char const plainmsg[] = "Plain text: ";
char const cryptmsg[] = "Cipher text: ";
bool encrypt = true;
int opt;
while ((opt = getopt(argc, argv, "d")) != -1) {
switch (opt) {
case 'd':
sign = -1;
encrypt = false;
break;
default:
fprintf(stderr, "Unrecogized command line argument:'-%i'\n", opt);
fprintf(stderr, "\n%s\n", usage);
return 1;
}
}
if (argc - optind != 1) {
fprintf(stderr, "%s requires one argument and one only\n", argv[0]);
fprintf(stderr, "\n%s\n", usage);
return 1;
}
// Convert argument into array of shifts
char const *const restrict key = argv[optind];
size_t const keylen = strlen(key);
char shifts[keylen];
char const *restrict plaintext = NULL;
for (size_t i = 0; i < keylen; i++) {
if (!(isalpha(key[i]))) {
fprintf(stderr, "Invalid key\n");
return 2;
}
char const charcase = (isupper(key[i])) ? 'A' : 'a';
// If decrypting, shifts will be negative.
// This line would turn "bacon" into {1, 0, 2, 14, 13}
shifts[i] = (key[i] - charcase) * sign;
}
do {
fflush(stdout);
// Print "Plain text: " if encrypting and "Cipher text: " if
// decrypting
printf("%s", (encrypt) ? plainmsg : cryptmsg);
plaintext = get_input();
if (plaintext == NULL) {
fprintf(stderr, "Error getting input\n");
return 4;
}
} while (strcmp(plaintext, "") == 0); // Reprompt if entry is empty
size_t const plainlen = strlen(plaintext);
char* const restrict ciphertext = calloc(plainlen + 1, sizeof *ciphertext);
if (ciphertext == NULL) {
fprintf(stderr, "Memory error\n");
return 5;
}
for (size_t i = 0, j = 0; i < plainlen; i++) {
// Skip non-alphabetical characters
if (!(isalpha(plaintext[i]))) {
ciphertext[i] = plaintext[i];
continue;
}
// Check case
char const charcase = (isupper(plaintext[i])) ? 'A' : 'a';
// Wrapping conversion algorithm
ciphertext[i] = ((plaintext[i] + shifts[j] - charcase + NUMLETTERS) % NUMLETTERS) + charcase;
j = (j+1) % keylen;
}
ciphertext[plainlen] = '\0';
printf("%s%s\n", (encrypt) ? cryptmsg : plainmsg, ciphertext);
free(ciphertext);
// Silence warnings about const not being maintained in cast to void*
free((char*) plaintext);
return 0;
}
char *get_input(void) {
char *const restrict buf = malloc(BUFSIZE * sizeof (char));
if (buf == NULL) {
return NULL;
}
fgets(buf, BUFSIZE, stdin);
// Get rid of newline
size_t const len = strlen(buf);
if (buf[len - 1] == '\n') buf[len - 1] = '\0';
return buf;
}
- Output:
$ ./vigenere VIGENERECIPHER Plain text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Cipher text: Wmceei klg Rpifvmeugx, qp wqv! Ioi avey xuek fkbt, alv xtgaf xyev kpagy! $ ./vigenere -d VIGENERECIPHER Cipher text: Wmceei klg Rpifvmeugx, qp wqv! Ioi avey xuek fkbt, alv xtgaf xyev kpagy! Plain text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch!
C#
using System;
namespace VigenereCipher
{
class VCipher
{
public string encrypt(string txt, string pw, int d)
{
int pwi = 0, tmp;
string ns = "";
txt = txt.ToUpper();
pw = pw.ToUpper();
foreach (char t in txt)
{
if (t < 65) continue;
tmp = t - 65 + d * (pw[pwi] - 65);
if (tmp < 0) tmp += 26;
ns += Convert.ToChar(65 + ( tmp % 26) );
if (++pwi == pw.Length) pwi = 0;
}
return ns;
}
};
class Program
{
static void Main(string[] args)
{
VCipher v = new VCipher();
string s0 = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!",
pw = "VIGENERECIPHER";
Console.WriteLine(s0 + "\n" + pw + "\n");
string s1 = v.encrypt(s0, pw, 1);
Console.WriteLine("Encrypted: " + s1);
s1 = v.encrypt(s1, "VIGENERECIPHER", -1);
Console.WriteLine("Decrypted: " + s1);
Console.WriteLine("\nPress any key to continue...");
Console.ReadKey();
}
}
}
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! VIGENERECIPHER Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
C++
#include <iostream>
#include <string>
using namespace std;
class Vigenere
{
public:
string key;
Vigenere(string key)
{
for(int i = 0; i < key.size(); ++i)
{
if(key[i] >= 'A' && key[i] <= 'Z')
this->key += key[i];
else if(key[i] >= 'a' && key[i] <= 'z')
this->key += key[i] + 'A' - 'a';
}
}
string encrypt(string text)
{
string out;
for(int i = 0, j = 0; i < text.length(); ++i)
{
char c = text[i];
if(c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if(c < 'A' || c > 'Z')
continue;
out += (c + key[j] - 2*'A') % 26 + 'A';
j = (j + 1) % key.length();
}
return out;
}
string decrypt(string text)
{
string out;
for(int i = 0, j = 0; i < text.length(); ++i)
{
char c = text[i];
if(c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if(c < 'A' || c > 'Z')
continue;
out += (c - key[j] + 26) % 26 + 'A';
j = (j + 1) % key.length();
}
return out;
}
};
int main()
{
Vigenere cipher("VIGENERECIPHER");
string original = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
string encrypted = cipher.encrypt(original);
string decrypted = cipher.decrypt(encrypted);
cout << original << endl;
cout << "Encrypted: " << encrypted << endl;
cout << "Decrypted: " << decrypted << endl;
}
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Ceylon
shared void run() {
function normalize(String text) => text.uppercased.filter(Character.letter);
function crypt(String text, String key, Character(Character, Character) transform) => String {
for ([a, b] in zipPairs(normalize(text), normalize(key).cycled))
transform(a, b)
};
function encrypt(String clearText, String key) =>
crypt(clearText, key, (Character a, Character b) =>
('A'.integer + ((a.integer + b.integer - 130) % 26)).character);
function decrypt(String cipherText, String key) =>
crypt(cipherText, key, (Character a, Character b) =>
('A'.integer + ((a.integer - b.integer + 26) % 26)).character);
value key = "VIGENERECIPHER";
value message = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
value encrypted = encrypt(message, key);
value decrypted = decrypt(encrypted, key);
print(encrypted);
print(decrypted);
}
Clojure
Requires Clojure 1.2.
(ns org.rosettacode.clojure.vigenere
(:require [clojure.string :as string]))
; convert letter to offset from \A
(defn to-num [char] (- (int char) (int \A)))
; convert number to letter, treating it as modulo 26 offset from \A
(defn from-num [num] (char (+ (mod num 26) (int \A))))
; Convert a string to a sequence of just the letters as uppercase chars
(defn to-normalized-seq [str]
(map #'first (re-seq #"[A-Z]" (string/upper-case str))))
; add (op=+) or subtract (op=-) the numerical value of the key letter from the
; text letter.
(defn crypt1 [op text key]
(from-num (apply op (list (to-num text) (to-num key)))))
(defn crypt [op text key]
(let [xcrypt1 (partial #'crypt1 op)]
(apply #'str
(map xcrypt1 (to-normalized-seq text)
(cycle (to-normalized-seq key))))))
; encipher a text
(defn encrypt [plaintext key] (crypt #'+ plaintext key))
; decipher a text
(defn decrypt [ciphertext key] (crypt #'- ciphertext key))
Demonstration code:
(ns org.rosettacode.clojure.test-vigenere
(:require [org.rosettacode.clojure.vigenere :as vigenere]))
(let
[ plaintext "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
key "Vigenere cipher"
ciphertext (vigenere/encrypt plaintext key)
recovered (vigenere/decrypt ciphertext key) ]
(doall (map (fn [[k v]] (printf "%9s: %s\n" k v))
[ ["Original" plaintext] ["Key" key] ["Encrypted" ciphertext] ["Decrypted" recovered] ])))
- Output:
Original: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Key: Vigenere cipher Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
CoffeeScript
# Simple helper since charCodeAt is quite long to write.
code = (char) -> char.charCodeAt()
encrypt = (text, key) ->
res = []
j = 0
for c in text.toUpperCase()
continue if c < 'A' or c > 'Z'
res.push ((code c) + (code key[j]) - 130) % 26 + 65
j = ++j % key.length
String.fromCharCode res...
decrypt = (text, key) ->
res = []
j = 0
for c in text.toUpperCase()
continue if c < 'A' or c > 'Z'
res.push ((code c) - (code key[j]) + 26) % 26 + 65
j = ++j % key.length
String.fromCharCode res...
# Trying it out
key = "VIGENERECIPHER"
original = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
encrypted = encrypt original, key
console.log "Original : #{original}"
console.log "Encrypted : #{encrypted}"
console.log "Decrypted : #{decrypt encrypted, key}"
Original : Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Encrypted : WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted : BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Common Lisp
Main version
This doesn't assume anything about character codes other than A-Z being a contiguous block (but still, we could be using EBCDIC. Who knows.)
(defun strip (s)
(remove-if-not
(lambda (c) (char<= #\A c #\Z))
(string-upcase s)))
(defun vigenère (s key &key decipher
&aux (A (char-code #\A))
(op (if decipher #'- #'+)))
(labels
((to-char (c) (code-char (+ c A)))
(to-code (c) (- (char-code c) A)))
(let ((k (map 'list #'to-code (strip key))))
(setf (cdr (last k)) k)
(map 'string
(lambda (c)
(prog1
(to-char
(mod (funcall op (to-code c) (car k)) 26))
(setf k (cdr k))))
(strip s)))))
(let* ((msg "Beware the Jabberwock... The jaws that... the claws that catch!")
(key "vigenere cipher")
(enc (vigenère msg key))
(dec (vigenère enc key :decipher t)))
(format t "msg: ~a~%enc: ~a~%dec: ~a~%" msg enc dec))
- Output:
msg: Beware the Jabberwock... The jaws that... the claws that catch! enc: WMCEEIKLGRPIFVMEUGXXYILILZXYVBZLRGCEYAIOEKXIZGU dec: BEWARETHEJABBERWOCKTHEJAWSTHATTHECLAWSTHATCATCH
Alternate version
No string to circular list conversion here.
1. Program
(defconstant +a+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
(defun strip (s)
(string-upcase (remove-if-not 'alpha-char-p s)))
(defun vigenere (txt key &key plain &aux (p (if plain -1 1)))
(let ((txt (strip txt)) (key (strip key)) (i -1))
(map 'string
(lambda (c)
(setf i (mod (1+ i) (length key)))
(char +a+ (mod (+ (position c +a+) (* p (position (elt key i) +a+))) 26)))
txt)))
2. Execution
(vigenere "« Through the Looking-Glass »" "Lewis Carroll") (vigenere "ELNWMIHKYSWZZOEVYILRJG" "Lewis Carroll" :plain t)
- Output:
"ELNWMIHKYSWZZOEVYILRJG" "THROUGHTHELOOKINGGLASS"
D
import std.stdio, std.string;
string encrypt(in string txt, in string key) pure @safe
in {
assert(key.removechars("^A-Z") == key);
} body {
string res;
foreach (immutable i, immutable c; txt.toUpper.removechars("^A-Z"))
res ~= (c + key[i % $] - 2 * 'A') % 26 + 'A';
return res;
}
string decrypt(in string txt, in string key) pure @safe
in {
assert(key.removechars("^A-Z") == key);
} body {
string res;
foreach (immutable i, immutable c; txt.toUpper.removechars("^A-Z"))
res ~= (c - key[i % $] + 26) % 26 + 'A';
return res;
}
void main() {
immutable key = "VIGENERECIPHER";
immutable original = "Beware the Jabberwock, my son!" ~
" The jaws that bite, the claws that catch!";
immutable encoded = original.encrypt(key);
writeln(encoded, "\n", encoded.decrypt(key));
}
- Output:
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Alternative Version
import std.stdio, std.range, std.ascii, std.string, std.algorithm,
std.conv;
immutable mod = (in int m, in int n) pure nothrow @safe @nogc =>
((m % n) + n) % n;
immutable _s2v = (in string s) pure /*nothrow*/ @safe =>
s.toUpper.removechars("^A-Z").map!q{ a - 'A' };
string _v2s(R)(R v) pure /*nothrow*/ @safe {
return v.map!(x => uppercase[x.mod(26)]).text;
}
immutable encrypt = (in string txt, in string key) pure /*nothrow*/ @safe =>
txt._s2v.zip(key._s2v.cycle).map!q{ a[0] + a[1] }._v2s;
immutable decrypt = (in string txt, in string key) pure /*nothrow*/ @safe =>
txt._s2v.zip(key._s2v.cycle).map!q{ a[0] - a[1] }._v2s;
void main() {
immutable key = "Vigenere Cipher!!!";
immutable original = "Beware the Jabberwock, my son!" ~
" The jaws that bite, the claws that catch!";
immutable encoded = original.encrypt(key);
writeln(encoded, "\n", encoded.decrypt(key));
}
The output is the same.
Delphi
function UpperAlphaOnly(S: string): string;
{Remove all }
var I: integer;
begin
Result:='';
S:=UpperCase(S);
for I:=1 to Length(S) do
if S[I] in ['A'..'Z'] then Result:=Result+S[I];
end;
function VigenereEncrypt(Text, Key: string): string;
{Encrypt Text using specified key}
var KInx,TInx,I: integer;
var TC: byte;
begin
Result:='';
{Force Text and Key upper case}
Text:=UpperAlphaOnly(Text);
Key:=UpperAlphaOnly(Key);
{Point to first Key-character}
KInx:=1;
for I:=1 to Length(Text) do
begin
{Offset Text-char by key-char amount}
TC:=byte(Text[I])-byte('A')+Byte(Key[KInx]);
{if it is shifted past "Z", wrap back around past "A"}
if TC>Byte('Z') then TC:=byte('@')+(TC-Byte('Z'));
{Store in output string}
Result:=Result+Char(TC);
{Point to next Key-char}
Inc(Kinx);
{If index post end of key, start over}
if KInx>Length(Key) then KInx:=1;
end;
end;
function VigenereDecrypt(Text, Key: string): string;
{Encrypt Text using specified key}
var KInx,TInx,I: integer;
var TC: byte;
begin
Result:='';
{For Key and text uppercase}
Text:=UpperAlphaOnly(Text);
Key:=UpperAlphaOnly(Key);
KInx:=1;
for I:=1 to Length(Text) do
begin
{subtrack key-char from text-char}
TC:=byte(Text[I])-Byte(Key[Kinx])+Byte('A');
{if result below "A" wrap back around to "Z"}
if TC<Byte('A') then TC:=(byte('Z')-((Byte('A')-TC)))+1;
{store in result}
Result:=Result+Char(TC);
{Point to next key char}
Inc(Kinx);
{Past the end, start over}
if KInx>Length(Key) then KInx:=1;
end;
end;
const TestKey = 'VIGENERECIPHER';
const TestStr = 'Beware the Jabberwock, my son! The jaws that bite, the claws that catch!';
procedure VigenereCipher(Memo: TMemo);
var S: string;
begin
{Show plain text}
Memo.Lines.Add(TestStr);
S:=VigenereEncrypt(TestStr, TestKey);
{Show encrypted text}
Memo.Lines.Add(S);
S:=VigenereDecrypt(S, TestKey);
{Show decrypted text}
Memo.Lines.Add(S);
end;
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH Elapsed Time: 4.549 ms.
EasyLang
func$ encr txt$ pw$ d .
txt$[] = strchars txt$
for c$ in strchars pw$
pw[] &= strcode c$ - 65
.
for c$ in txt$[]
c = strcode c$
if c >= 97
c -= 32
.
if c >= 65 and c <= 97
pwi = (pwi + 1) mod1 len pw[]
c = (c - 65 + d * pw[pwi]) mod 26 + 65
r$ &= strchar c
.
.
return r$
.
s$ = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
pw$ = "VIGENERECIPHER"
r$ = encr s$ pw$ 1
print r$
print encr r$ pw$ -1
Elena
ELENA 6.x :
import system'text;
import system'culture;
import system'math;
import system'routines;
import extensions;
class VCipher
{
string encrypt(string txt, string pw, int d)
{
auto output := new TextBuilder();
int pwi := 0;
string PW := pw.toUpper();
var TXT := txt.toUpper();
foreach(char t; in TXT)
{
if (t < $65) $continue;
int tmp := t - 65 + d * (pw[pwi] - 65);
if (tmp < 0) tmp += 26;
output.write((65 + tmp.mod(26)).toChar());
pwi++;
if (pwi == PW.Length) { pwi := 0 }
};
^ output.Value
}
}
public program()
{
var v := new VCipher();
var s0 := "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
var pw := "VIGENERECIPHER";
console.printLine(s0,newLineConstant,pw,newLineConstant);
var s1 := v.encrypt(s0, pw, 1);
console.printLine("Encrypted:",s1);
s1 := v.encrypt(s1, "VIGENERECIPHER", -1);
console.printLine("Decrypted:",s1);
console.printLine("Press any key to continue..");
console.readChar()
}
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! VIGENERECIPHER Encrypted:WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted:BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH Press any key to continue..
Elixir
defmodule VigenereCipher do
@base ?A
@size ?Z - @base + 1
def encrypt(text, key), do: crypt(text, key, 1)
def decrypt(text, key), do: crypt(text, key, -1)
defp crypt(text, key, dir) do
text = String.upcase(text) |> String.replace(~r/[^A-Z]/, "") |> to_char_list
key_iterator = String.upcase(key) |> String.replace(~r/[^A-Z]/, "") |> to_char_list
|> Enum.map(fn c -> (c - @base) * dir end) |> Stream.cycle
Enum.zip(text, key_iterator)
|> Enum.reduce('', fn {char, offset}, ciphertext ->
[rem(char - @base + offset + @size, @size) + @base | ciphertext]
end)
|> Enum.reverse |> List.to_string
end
end
plaintext = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
key = "Vigenere cipher"
ciphertext = VigenereCipher.encrypt(plaintext, key)
recovered = VigenereCipher.decrypt(ciphertext, key)
IO.puts "Original: #{plaintext}"
IO.puts "Encrypted: #{ciphertext}"
IO.puts "Decrypted: #{recovered}"
- Output:
Original: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Erlang
Erlang is not ideal for string manipulation, but with some utility function definitions it can express this fairly elegantly:
% Erlang implementation of Vigenère cipher
-module(vigenere).
-export([encrypt/2, decrypt/2]).
-import(lists, [append/2, filter/2, map/2, zipwith/3]).
% Utility functions for character tests and conversions
isupper([C|_]) -> isupper(C);
isupper(C) -> (C >= $A) and (C =< $Z).
islower([C|_]) -> islower(C);
islower(C) -> (C >= $a) and (C =< $z).
isalpha([C|_]) -> isalpha(C);
isalpha(C) -> isupper(C) or islower(C).
toupper(S) when is_list(S) -> lists:map(fun toupper/1, S);
toupper(C) when (C >= $a) and (C =< $z) -> C - $a + $A;
toupper(C) -> C.
% modulo function that normalizes into positive range for positive divisor
mod(X,Y) -> (X rem Y + Y) rem Y.
% convert letter to position in alphabet (A=0,B=1,...,Y=24,Z=25).
to_pos(L) when L >= $A, L =< $Z -> L - $A.
% convert position in alphabet back to letter
from_pos(N) -> mod(N, 26) + $A.
% encode the given letter given the single-letter key
encipher(P, K) -> from_pos(to_pos(P) + to_pos(K)).
% decode the given letter given the single-letter key
decipher(C, K) -> from_pos(to_pos(C) - to_pos(K)).
% extend a list by repeating it until it is at least N elements long
cycle_to(N, List) when length(List) >= N -> List;
cycle_to(N, List) -> append(List, cycle_to(N-length(List), List)).
% Encryption prep: reduce string to only its letters, in uppercase
normalize(Str) -> toupper(filter(fun isalpha/1, Str)).
crypt(RawText, RawKey, Func) ->
PlainText = normalize(RawText),
zipwith(Func, PlainText, cycle_to(length(PlainText), normalize(RawKey))).
encrypt(Text, Key) -> crypt(Text, Key, fun encipher/2).
decrypt(Text, Key) -> crypt(Text, Key, fun decipher/2).
Demonstration code:
-module(testvigenere).
-import(vigenere,[encrypt/2, decrypt/2]).
main(_) ->
Key = "Vigenere cipher",
CipherText = encrypt("Beware the Jabberwock, my son! The jaws that bite, the claws that catch!", Key),
RecoveredText = decrypt(CipherText, Key),
io:fwrite("Ciphertext: ~s~nDecrypted: ~s~n", [CipherText, RecoveredText]).
- Output:
Ciphertext: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
F#
module vigenere =
let keyschedule (key:string) =
let s = key.ToUpper().ToCharArray() |> Array.filter System.Char.IsLetter
let l = Array.length s
(fun n -> int s.[n % l])
let enc k c = ((c + k - 130) % 26) + 65
let dec k c = ((c - k + 130) % 26) + 65
let crypt f key = Array.mapi (fun n c -> f (key n) c |> char)
let encrypt key (plaintext:string) =
plaintext.ToUpper().ToCharArray()
|> Array.filter System.Char.IsLetter
|> Array.map int
|> crypt enc (keyschedule key)
|> (fun a -> new string(a))
let decrypt key (ciphertext:string) =
ciphertext.ToUpper().ToCharArray()
|> Array.map int
|> crypt dec (keyschedule key)
|> (fun a -> new string(a))
let passwd = "Vigenere Cipher"
let cipher = vigenere.encrypt passwd "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
let plain = vigenere.decrypt passwd cipher
printfn "%s\n%s" cipher plain
C:\src\fsharp>fsi vigenere.fsx WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Factor
USING: arrays ascii formatting kernel math math.functions
math.order sequences ;
IN: rosetta-code.vigenere-cipher
: mult-pad ( key input -- x )
[ length ] bi@ 2dup < [ swap ] when / ceiling ;
: lengthen-pad ( key input -- rep-key input )
[ mult-pad ] 2keep [ <repetition> concat ] dip
[ length ] keep [ head ] dip ;
: normalize ( str -- only-upper-letters )
>upper [ LETTER? ] filter ;
: vigenere-encrypt ( key input -- ecrypted )
[ normalize ] bi@ lengthen-pad
[ [ CHAR: A - ] map ] bi@ [ + 26 mod CHAR: A + ] 2map ;
: vigenere-decrypt ( key input -- decrypted )
[ normalize ] bi@ lengthen-pad [ [ CHAR: A - ] map ] bi@
[ - 26 - abs 26 mod CHAR: A + ] 2map ;
: main ( -- )
"Vigenere cipher" dup
"Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
2dup "Key: %s\nInput: %s\n" printf
vigenere-encrypt dup "Encrypted: %s\n" printf
vigenere-decrypt "Decrypted: %s\n" printf ;
MAIN: main
- Output:
Key: Vigenere cipher Input: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Fortran
program vigenere_cipher
implicit none
character(80) :: plaintext = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!", &
ciphertext = ""
character(14) :: key = "VIGENERECIPHER"
call encrypt(plaintext, ciphertext, key)
write(*,*) plaintext
write(*,*) ciphertext
call decrypt(ciphertext, plaintext, key)
write(*,*) plaintext
contains
subroutine encrypt(intxt, outtxt, k)
character(*), intent(in) :: intxt, k
character(*), intent(out) :: outtxt
integer :: chrn
integer :: cp = 1, kp = 1
integer :: i
outtxt = ""
do i = 1, len(trim(intxt))
select case(intxt(i:i))
case ("A":"Z", "a":"z")
select case(intxt(i:i))
case("a":"z")
chrn = iachar(intxt(i:i)) - 32
case default
chrn = iachar(intxt(i:i))
end select
outtxt(cp:cp) = achar(modulo(chrn + iachar(k(kp:kp)), 26) + 65)
cp = cp + 1
kp = kp + 1
if(kp > len(k)) kp = kp - len(k)
end select
end do
end subroutine
subroutine decrypt(intxt, outtxt, k)
character(*), intent(in) :: intxt, k
character(*), intent(out) :: outtxt
integer :: chrn
integer :: cp = 1, kp = 1
integer :: i
outtxt = ""
do i = 1, len(trim(intxt))
chrn = iachar(intxt(i:i))
outtxt(cp:cp) = achar(modulo(chrn - iachar(k(kp:kp)), 26) + 65)
cp = cp + 1
kp = kp + 1
if(kp > len(k)) kp = kp - len(k)
end do
end subroutine
end program
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
FreeBASIC
Function Filtrar(cadorigen As String) As String
Dim As String letra
Dim As String filtrado = ""
For i As Integer = 1 To Len(cadorigen)
letra = Ucase(Mid(cadorigen, i, 1))
If Instr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", letra) Then filtrado += letra
Next i
Return filtrado
End Function
Function Encriptar(texto As String, llave As String) As String
texto = Filtrar(texto)
Dim As String mSS, kSS, letra, cifrado = ""
Dim As Integer m, k, c, j = 1
For i As Integer = 1 To Len(texto)
mSS = Mid(texto, i, 1)
m = Asc(mSS) - Asc("A")
kSS = Mid(llave, j, 1)
k = Asc(kSS) - Asc("A")
j = (j Mod Len(llave)) + 1
c = (m + k) Mod 26
letra = Chr(Asc("A") + c)
cifrado += letra
Next i
Return cifrado
End Function
Function DesEncriptar(texto As String, llave As String) As String
Dim As String mSS, kSS, letra, descifrado = ""
Dim As Integer m, k, c, j = 1
For i As Integer = 1 To Len(texto)
mSS = Mid(texto, i, 1)
m = Asc(mSS) - Asc("A")
kSS = Mid(llave, j, 1)
k = Asc(kSS) - Asc("A")
j = (j Mod Len(llave)) + 1
c = (m - k + 26) Mod 26
letra = Chr(Asc("A")+c)
descifrado += letra
Next i
Return descifrado
End Function
Dim Shared As String llave
llave = Filtrar("vigenerecipher")
Dim As String cadorigen = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
Print cadorigen
Print llave
Dim As String cadcifrada = Encriptar(cadorigen, llave)
Print " Cifrado: "; cadcifrada
Print "Descifrado: "; DesEncriptar(cadcifrada, llave)
Sleep
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! VIGENERECIPHER Cifrado: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Descifrado: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Go
package main
import "fmt"
type vkey string
func newVigenère(key string) (vkey, bool) {
v := vkey(upperOnly(key))
return v, len(v) > 0 // key length 0 invalid
}
func (k vkey) encipher(pt string) string {
ct := upperOnly(pt)
for i, c := range ct {
ct[i] = 'A' + (c-'A'+k[i%len(k)]-'A')%26
}
return string(ct)
}
func (k vkey) decipher(ct string) (string, bool) {
pt := make([]byte, len(ct))
for i := range pt {
c := ct[i]
if c < 'A' || c > 'Z' {
return "", false // invalid ciphertext
}
pt[i] = 'A' + (c-k[i%len(k)]+26)%26
}
return string(pt), true
}
// upperOnly extracts letters A-Z, a-z from a string and
// returns them all upper case in a byte slice.
// Useful for vkey constructor and encipher function.
func upperOnly(s string) []byte {
u := make([]byte, 0, len(s))
for i := 0; i < len(s); i++ {
c := s[i]
if c >= 'A' && c <= 'Z' {
u = append(u, c)
} else if c >= 'a' && c <= 'z' {
u = append(u, c-32)
}
}
return u
}
const testKey = "Vigenère Cipher"
const testPT = `Beware the Jabberwock, my son!
The jaws that bite, the claws that catch!`
func main() {
fmt.Println("Supplied key: ", testKey)
v, ok := newVigenère(testKey)
if !ok {
fmt.Println("Invalid key")
return
}
fmt.Println("Effective key:", v)
fmt.Println("Plain text:", testPT)
ct := v.encipher(testPT)
fmt.Println("Enciphered:", ct)
dt, ok := v.decipher(ct)
if !ok {
fmt.Println("Invalid ciphertext")
return
}
fmt.Println("Deciphered:", dt)
}
- Output:
Supplied key: Vigenère Cipher Effective key: VIGENRECIPHER Plain text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Enciphered: WMCEEVXJMYHFSZZCSPBQAADUXYZRGAFKLCBQPXVOPKGYRAUBWHXTVBIL Deciphered: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Haskell
import Data.Char
import Text.Printf
-- Perform encryption or decryption, depending on f.
crypt f key = map toLetter . zipWith f (cycle key)
where toLetter = chr . (+) (ord 'A')
-- Encrypt or decrypt one letter.
enc k c = (ord k + ord c) `mod` 26
dec k c = (ord c - ord k) `mod` 26
-- Given a key, encrypt or decrypt an input string.
encrypt = crypt enc
decrypt = crypt dec
-- Convert a string to have only upper case letters.
convert = map toUpper . filter isLetter
main :: IO ()
main = do
let key = "VIGENERECIPHER"
text = "Beware the Jabberwock, my son! The jaws that bite, "
++ "the claws that catch!"
encr = encrypt key $ convert text
decr = decrypt key encr
printf " Input: %s\n Key: %s\nEncrypted: %s\nDecrypted: %s\n"
text key encr decr
- Output:
Input: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Key: VIGENERECIPHER Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Icon and Unicon
The following helper procedures will be of general use with classical cryptography tasks.
- Output:
Key = VIGENERECIPHER Plain Text = Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Normalized = BEWAR ETHEJ ABBER WOCKM YSONT HEJAW STHAT BITET HECLA WSTHA TCATCH Enciphered = WMCEE IKLGR PIFVM EUGXQ PWQVI OIAVE YXUEK FKBTA LVXTG AFXYE VKPAGY Deciphered = BEWAR ETHEJ ABBER WOCKM YSONT HEJAW STHAT BITET HECLA WSTHA TCATCH
J
Solution:
Using vig
from the convert/misc/vig addon:
ALPHA=: (65,:26) ];.0 a. NB. Character Set
preprocess=: (#~ e.&ALPHA)@toupper NB. force uppercase and discard non-alpha chars
vigEncryptRC=: 0 vig ALPHA preprocess
vigDecryptRC=: 1 vig ALPHA preprocess
Example Use:
'VIGENERECIPHER' vigEncryptRC 'Beware the Jabberwock, my son! The jaws that bite, the claws that catch!'
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY
'VIGENERECIPHER' vigDecryptRC 'WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY'
BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Java
public class VigenereCipher {
public static void main(String[] args) {
String key = "VIGENERECIPHER";
String ori = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
String enc = encrypt(ori, key);
System.out.println(enc);
System.out.println(decrypt(enc, key));
}
static String encrypt(String text, final String key) {
String res = "";
text = text.toUpperCase();
for (int i = 0, j = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (c < 'A' || c > 'Z') continue;
res += (char)((c + key.charAt(j) - 2 * 'A') % 26 + 'A');
j = ++j % key.length();
}
return res;
}
static String decrypt(String text, final String key) {
String res = "";
text = text.toUpperCase();
for (int i = 0, j = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (c < 'A' || c > 'Z') continue;
res += (char)((c - key.charAt(j) + 26) % 26 + 'A');
j = ++j % key.length();
}
return res;
}
}
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Alternative Version
import com.google.common.collect.Streams;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.nio.charset.StandardCharsets.US_ASCII;
public class VigenereCipher {
private final static int LOWER = 'A';
private final static int UPPER = 'Z';
private final static int SIZE = UPPER - LOWER + 1;
private final Supplier<Stream<Character>> maskStream;
public VigenereCipher(final String key) {
final String mask = new String(key.getBytes(US_ASCII)).toUpperCase();
maskStream = () ->
Stream.iterate(0, i -> (i+1) % mask.length()).map(mask::charAt);
}
private String transform(final String text, final boolean encode) {
final Stream<Integer> textStream = text.toUpperCase().chars().boxed()
.filter(i -> i >= LOWER && i <= UPPER);
return Streams.zip(textStream, maskStream.get(), (c, m) ->
encode ? c + m - 2 * LOWER : c - m + SIZE)
.map(c -> Character.toString(c % SIZE + LOWER))
.collect(Collectors.joining());
}
public String encrypt(final String plaintext) {
return transform(plaintext,true);
}
public String decrypt(final String ciphertext) {
return transform(ciphertext,false);
}
}
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class VigenereCipherTest {
private static final VigenereCipher Vigenere = new VigenereCipher("VIGENERECIPHER");
@Test
@DisplayName("encipher/decipher round-trip succeeds")
void vigenereCipherTest() {
final String input = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
final String expectEncrypted = "WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY";
final String expectDecrypted = "BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH";
final String ciphertext = Vigenere.encrypt(input);
assertEquals(expectEncrypted, ciphertext);
final String plaintext = Vigenere.decrypt(ciphertext);
assertEquals(expectDecrypted, plaintext);
}
}
JavaScript
// helpers
// helper
function ordA(a) {
return a.charCodeAt(0) - 65;
}
// vigenere
function vigenere(text, key, decode) {
var i = 0, b;
key = key.toUpperCase().replace(/[^A-Z]/g, '');
return text.toUpperCase().replace(/[^A-Z]/g, '').replace(/[A-Z]/g, function(a) {
b = key[i++ % key.length];
return String.fromCharCode(((ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26 + 65));
});
}
// example
var text = "The quick brown fox Jumped over the lazy Dog the lazy dog lazy dog dog";
var key = 'alex';
var enc = vigenere(text,key);
var dec = vigenere(enc,key,true);
console.log(enc);
console.log(dec);
jq
Works with gojq, the Go implementation of jq
def vigenere(text; key; encryptp):
# retain alphabetic characters only
def n:
ascii_upcase | explode | map(select(65 <= . and . <= 90)) | [., length];
(text | n) as [$xtext, $length]
| (key | n) as [$xkey, $keylength]
| reduce range(0; $length) as $i (null;
($i % $keylength) as $ki
| . + [if encryptp
then (($xtext[$i] + $xkey[$ki] - 130) % 26) + 65
else (($xtext[$i] - $xkey[$ki] + 26) % 26) + 65
end] )
| implode;
# Input: sample text
def example($key):
vigenere(.; $key; true)
| . as $encoded
| ., vigenere($encoded; $key; false) ;
"Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
| (., example("VIGENERECIPHER")),
"",
(., example("ROSETTACODE"))
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH Beware the Jabberwock, my son! The jaws that bite, the claws that catch! SSOEKXTJSMESPWVPHCMABWFBLLXCAYGWLRHTMMXTJSFPRKKXATTEOWGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Jsish
From Javascript entry.
/* Vigenère cipher, in Jsish */
"use strict";
function ordA(a:string):number {
return a.charCodeAt(0) - 65;
}
// vigenere
function vigenereCipher(text:string, key:string, decode:boolean=false):string {
var i = 0, b;
key = key.toUpperCase().replace(/[^A-Z]/g, '');
return text.toUpperCase().replace(/[^A-Z]/g, '').replace(/[A-Z]/g,
function(a:string, idx:number, str:string) {
b = key[i++ % key.length];
return String.fromCharCode(((ordA(a) + (decode ? 26 - ordA(b) : ordA(b))) % 26 + 65));
});
}
provide('vigenereCipher', 1);
if (Interp.conf('unitTest')) {
var text = "The quick brown fox Jumped over the lazy Dog the lazy dog lazy dog dog";
var key = 'jsish';
var enc = vigenereCipher(text, key);
; text;
; enc;
; vigenereCipher(enc, key, true);
}
/*
=!EXPECTSTART!=
text ==> The quick brown fox Jumped over the lazy Dog the lazy dog lazy dog dog
enc ==> CZMIBRUSTYXOVXVGBCEWNVWNLALPWSJRGVVPLPWSJRGVVPDIRFMGOVVP
vigenere(enc, key, true) ==> THEQUICKBROWNFOXJUMPEDOVERTHELAZYDOGTHELAZYDOGLAZYDOGDOG
=!EXPECTEND!=
*/
- Output:
prompt$ jsish -u vigenereCipher.jsi [PASS] vigenereCipher.jsi
Julia
→(a::Char, b::Char, ± = +) = 'A'+((a-'A')±(b-'A')+26)%26
←(a::Char, b::Char) = →(a,b,-)
cleanup(str) = filter(a-> a in 'A':'Z', collect(uppercase.(str)))
match_length(word, len) = repeat(word,len)[1:len]
function →(message::String, codeword::String, ↔ = →)
plaintext = cleanup(message)
key = match_length(cleanup(codeword),length(plaintext))
return String(plaintext .↔ key)
end
←(message::String, codeword::String) = →(message,codeword,←)
cyphertext = "I want spearmint gum" → "Gimme!"
println(cyphertext)
println(cyphertext ← "Gimme!")
- Output:
"OEMZXYXQMVSQZFKAU" "IWANTSPEARMINTGUM"
Kotlin
// version 1.1.3
fun vigenere(text: String, key: String, encrypt: Boolean = true): String {
val t = if (encrypt) text.toUpperCase() else text
val sb = StringBuilder()
var ki = 0
for (c in t) {
if (c !in 'A'..'Z') continue
val ci = if (encrypt)
(c.toInt() + key[ki].toInt() - 130) % 26
else
(c.toInt() - key[ki].toInt() + 26) % 26
sb.append((ci + 65).toChar())
ki = (ki + 1) % key.length
}
return sb.toString()
}
fun main(args: Array<String>) {
val key = "VIGENERECIPHER"
val text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
val encoded = vigenere(text, key)
println(encoded)
val decoded = vigenere(encoded, key, false)
println(decoded)
}
- Output:
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Lambdatalk
Only texts in uppercases [A-Z] and spaces.
{def vigenere
{def vigenere.map
{lambda {:code :key :txt}
{S.map
{{lambda {:code :txt :key :i}
{W.code2char
{+ {% {+ {W.char2code {W.get :i :txt}}
{if :code
then {W.char2code {W.get {% :i {W.length :key}} :key}}
else {- 26 {W.char2code {W.get {% :i {W.length :key}} :key}}} }}
26}
65}} } :code :txt :key}
{S.serie 0 {- {W.length :txt} 1}}} }}
{lambda {:code :key :txt}
{S.replace \s by in {vigenere.map :code :key {S.replace \s by in :txt}}} }}
-> vigenere
1) encode: {vigenere true LEMON ATTACK AT DAWN}
-> LXFOPVEFRNHR
2) decode: {vigenere false LEMON LXFOPVEFRNHR}
-> ATTACKATDAWN
Liberty BASIC
ori$ = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
key$ = filter$("vigenerecipher")
print ori$
print key$
enc$ = encrypt$(ori$, key$)
print enc$
dec$ = decrypt$(enc$, key$)
print dec$
end
function encrypt$(text$, key$)
flt$ = filter$(text$)
encrypt$ = ""
j = 1
for i = 1 to len(flt$)
m$ = mid$(flt$, i, 1)
m = asc(m$)-asc("A")
k$ = mid$(key$, j, 1)
k = asc(k$)-asc("A")
j = (j mod len(key$)) + 1
c = (m + k) mod 26
c$=chr$(asc("A")+c)
encrypt$=encrypt$+c$
next
end function
function decrypt$(flt$, key$)
decrypt$ = ""
j = 1
for i = 1 to len(flt$)
m$ = mid$(flt$, i, 1)
m = asc(m$)-asc("A")
k$ = mid$(key$, j, 1)
k = asc(k$)-asc("A")
j = (j mod len(key$)) + 1
c = (m - k + 26) mod 26
c$=chr$(asc("A")+c)
decrypt$=decrypt$+c$
next
end function
function filter$(ori$)
'a..z A..Z go caps, other skipped
filter$=""
for i = 1 to len(ori$)
c$ = upper$(mid$(ori$,i,1))
if instr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", c$) then filter$ = filter$ + c$
next
end function
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! VIGENERECIPHER WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Lua
function Encrypt( _msg, _key )
local msg = { _msg:upper():byte( 1, -1 ) }
local key = { _key:upper():byte( 1, -1 ) }
local enc = {}
local j, k = 1, 1
for i = 1, #msg do
if msg[i] >= string.byte('A') and msg[i] <= string.byte('Z') then
enc[k] = ( msg[i] + key[j] - 2*string.byte('A') ) % 26 + string.byte('A')
k = k + 1
if j == #key then j = 1 else j = j + 1 end
end
end
return string.char( unpack(enc) )
end
function Decrypt( _msg, _key )
local msg = { _msg:byte( 1, -1 ) }
local key = { _key:upper():byte( 1, -1 ) }
local dec = {}
local j = 1
for i = 1, #msg do
dec[i] = ( msg[i] - key[j] + 26 ) % 26 + string.byte('A')
if j == #key then j = 1 else j = j + 1 end
end
return string.char( unpack(dec) )
end
original = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
key = "VIGENERECIPHER";
encrypted = Encrypt( original, key )
decrypted = Decrypt( encrypted, key )
print( encrypted )
print( decrypted )
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Mathematica /Wolfram Language
encode[text_String, key_String] :=
Module[{textCode, keyCode},
textCode =
Cases[ToCharacterCode[
ToUpperCase@
text], _?(IntervalMemberQ[Interval@{65, 90}, #] &)] - 65;
keyCode =
Cases[ToCharacterCode[
ToUpperCase@
key], _?(IntervalMemberQ[Interval@{65, 90}, #] &)] - 65;
keyCode =
If[Length[textCode] < Length[keyCode],
keyCode[[;; Length@textCode]],
PadRight[keyCode, Length@textCode, keyCode]];
FromCharacterCode[Mod[textCode + keyCode, 26] + 65]]
decode[text_String, key_String] :=
Module[{textCode, keyCode},
textCode =
Cases[ToCharacterCode[
ToUpperCase@
text], _?(IntervalMemberQ[Interval@{65, 90}, #] &)] - 65;
keyCode =
Cases[ToCharacterCode[
ToUpperCase@
key], _?(IntervalMemberQ[Interval@{65, 90}, #] &)] - 65;
keyCode =
If[Length[textCode] < Length[keyCode],
keyCode[[;; Length@textCode]],
PadRight[keyCode, Length@textCode, keyCode]];
FromCharacterCode[Mod[textCode - keyCode, 26] + 65]]
key = "Vigenere Cipher"; text = "Beware the Jabberwock, my son! The jaws that bite, the claws \ that catch!"; code = encode[text, key] WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY decode[code, key] BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
NetRexx
/* NetRexx */
options replace format comments java crossref savelog symbols nobinary
pt = 'Attack at dawn!'
key = 'LEMON'
test(key, pt)
key = 'N' -- rot-13
test(key, pt)
key = 'B' -- Caesar
test(key, pt)
pt = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
key = 'A'
test(key, pt)
pt = sampledata()
key = 'Hamlet; Prince of Denmark'
test(key, pt)
return
method vigenere(meth, key, text) public static
select
when 'encipher'.abbrev(meth.lower, 1) then df = 1
when 'decipher'.abbrev(meth.lower, 1) then df = -1
otherwise signal IllegalArgumentException(meth 'must be "encipher" or "decipher"')
end
alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
text = stringscrubber(text)
key = stringscrubber(key)
code = ''
loop l_ = 1 to text.length()
M = alpha.pos(text.substr(l_, 1)) - 1
k_ = (l_ - 1) // key.length()
K = alpha.pos(key.substr(k_ + 1, 1)) - 1
C = mod((M + K * df), alpha.length())
C = alpha.substr(C + 1, 1)
code = code || C
end l_
return code
method vigenere_encipher(key, plaintext) public static
return vigenere('encipher', key, plaintext)
method vigenere_decipher(key, ciphertext) public static
return vigenere('decipher', key, ciphertext)
method mod(N = int, D = int) private static
return (D + (N // D)) // D
method stringscrubber(cleanup) private static
alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
cleanup = cleanup.upper.space(0)
loop label f_ forever
x_ = cleanup.verify(alpha)
if x_ = 0 then leave f_
cleanup = cleanup.changestr(cleanup.substr(x_, 1), '')
end f_
return cleanup
method test(key, pt) private static
ct = vigenere_encipher(key, pt)
display(ct)
dt = vigenere_decipher(key, ct)
display(dt)
return
method display(text) public static
line = ''
o_ = 0
loop c_ = 1 to text.length()
b_ = o_ // 5
o_ = o_ + 1
if b_ = 0 then line = line' '
line = line || text.substr(c_, 1)
end c_
say '....+....|'.copies(8)
loop label l_ forever
parse line w1 w2 w3 w4 w5 w6 W7 w8 w9 w10 w11 w12 line
pline = w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12
say pline.strip()
if line.strip().length() = 0 then leave l_
end l_
say
return
method sampledata() private static returns Rexx
NL = char('\n')
antic_disposition = Rexx[]
antic_disposition = [ -
Rexx("To be, or not to be--that is the question:" ), -
Rexx("Whether 'tis nobler in the mind to suffer" ), -
Rexx("The slings and arrows of outrageous fortune" ), -
Rexx("Or to take arms against a sea of troubles" ), -
Rexx("And by opposing end them. To die, to sleep--" ), -
Rexx("No more--and by a sleep to say we end" ), -
Rexx("The heartache, and the thousand natural shocks" ), -
Rexx("That flesh is heir to. 'Tis a consummation" ), -
Rexx("Devoutly to be wished. To die, to sleep--" ), -
Rexx("To sleep--perchance to dream: ay, there's the rub,"), -
Rexx("For in that sleep of death what dreams may come" ), -
Rexx("When we have shuffled off this mortal coil," ), -
Rexx("Must give us pause. There's the respect" ), -
Rexx("That makes calamity of so long life." ), -
Rexx("For who would bear the whips and scorns of time," ), -
Rexx("Th' oppressor's wrong, the proud man's contumely" ), -
Rexx("The pangs of despised love, the law's delay," ), -
Rexx("The insolence of office, and the spurns" ), -
Rexx("That patient merit of th' unworthy takes," ), -
Rexx("When he himself might his quietus make" ), -
Rexx("With a bare bodkin? Who would fardels bear," ), -
Rexx("To grunt and sweat under a weary life," ), -
Rexx("But that the dread of something after death," ), -
Rexx("The undiscovered country, from whose bourn" ), -
Rexx("No traveller returns, puzzles the will," ), -
Rexx("And makes us rather bear those ills we have" ), -
Rexx("Than fly to others that we know not of?" ), -
Rexx("Thus conscience does make cowards of us all," ), -
Rexx("And thus the native hue of resolution" ), -
Rexx("Is sicklied o'er with the pale cast of thought," ), -
Rexx("And enterprise of great pith and moment" ), -
Rexx("With this regard their currents turn awry" ), -
Rexx("And lose the name of action. -- Soft you now," ), -
Rexx("The fair Ophelia! -- Nymph, in thy orisons" ), -
Rexx("Be all my sins remembered." ) -
]
melancholy_dane = Rexx('')
loop l_ = 0 for antic_disposition.length
melancholy_dane = melancholy_dane || antic_disposition[l_] || NL
end l_
return melancholy_dane
- Output:
....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| LXFOP VEFRN HR ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| ATTAC KATDA WN ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| NGGNP XNGQN JA ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| ATTAC KATDA WN ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| BUUBD LBUEB XO ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| ATTAC KATDA WN ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| ABCDE FGHIJ KLMNO PQRST UVWXY Z ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| ABCDE FGHIJ KLMNO PQRST UVWXY Z ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| AONPS KCFBG QFSYK EGUSK RLQGP WMXFV JJIHM HVGUS EYILQ CMGIY MZKRR YRWHR FVBAH QDPBC XANPH OWUSJ EOWYB TDLKX DLASQ VHZQI BDTFD HKQLV FHRON KRGYD WRMOW DYOGM PXHRV QDCCU SSFUN XOUDF SIFIF LVGXC XOIRB NFWVR QLRWQ PIFNI SUWSF MYNOL NPELX WVIEV EQMHE APTYO AHAFW TCUVN VYFFO WUACB CAHME JETJP VULSN UXBFI JKJOZ DYFBR BVQRR JYSHF LPDVB QHMLW VLGQH WJWSF XEVZA OEWIX EGMEE LOSFI GADIO HMMJX ATIMF VLSWX FSARZ XAHME WETVX BHHSF WLJTA KNYEM XWFPP KBOIK MHRJQ HRFLS TFJYA VLBHJ HMLWZ ARKKS CATPF JJBTK ZSZVT NGSVD OEDPW MWVZR UTSHW XUMTD KREEN EEPDQ GASTX RPBZG CSMER ZVPWF EBWPR GHEEF HVGOI BDEGS JKBTR GTIXV YEKRV PBCIL HFZFY VCSJX UQPIY BDYLR LRFVG WQSQB XUQPR XNSAQ HXHGQ FGHZT YIGTE CKDSP PPTNK PRKRG TOIAO EFPVF RTGXP ELGJI GUXVA ETYKA PMEMX CKURT MHTIX UGNNY YTTJX TZVAJ JIBMH LVYSV VMMUR LMWZA DWMSY XWZMK VGPTT LFTGV JBFOW SZLBI OLVKF MCHXA JJRCV HTJVH ZTRXK SIPEM JELRT EKJDV LXIWO IUFEL TIKPR FVSFG SSEOD OAHUY KTUKM EFIOY KXUQU ENPSO ZZXGV LPQYB YUCSD ODGOO EPFHJ IVAQX FFYIY XEIBL TGCRL ELHMN IGYKI JULCK UDYLO XHLAE CXVJU FRMRK RVSQT PEHNM UCZSY KEARL PDVOF SIKHK PNVAS PQSJZ OKYMT TFWVD EAPKI BHHHB QSDKR EOZAT GUABH YGFOP NZDKR BSFSI GPKQI GLIJR JEQSF VBTUZ RBHJQ PMPWJ GSRDW ZDOTT PTTAV KNUXC KWLBG GYDHN PPRMT IXEKW STIKE QAKZP TTLRW BFURP XKNWL GTIJB LGMCH MWVQE EYFWH RGETL BUAIC CTCUT BUIHM HRNYE FPHCF TSGHF NGASI SRAGT EWKPR AALXA ZIAAQ DMLRG TYFBP SAYWU TRTYO CGNQW EQMVW IEDPH ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| TOBEO RNOTT OBETH ATIST HEQUE STION WHETH ERTIS NOBLE RINTH EMIND TOSUF FERTH ESLIN GSAND ARROW SOFOU TRAGE OUSFO RTUNE ORTOT AKEAR MSAGA INSTA SEAOF TROUB LESAN DBYOP POSIN GENDT HEMTO DIETO SLEEP NOMOR EANDB YASLE EPTOS AYWEE NDTHE HEART ACHEA NDTHE THOUS ANDNA TURAL SHOCK STHAT FLESH ISHEI RTOTI SACON SUMMA TIOND EVOUT LYTOB EWISH EDTOD IETOS LEEPT OSLEE PPERC HANCE TODRE AMAYT HERES THERU BFORI NTHAT SLEEP OFDEA THWHA TDREA MSMAY COMEW HENWE HAVES HUFFL EDOFF THISM ORTAL COILM USTGI VEUSP AUSET HERES THERE SPECT THATM AKESC ALAMI TYOFS OLONG LIFEF ORWHO WOULD BEART HEWHI PSAND SCORN SOFTI METHO PPRES SORSW RONGT HEPRO UDMAN SCONT UMELY THEPA NGSOF DESPI SEDLO VETHE LAWSD ELAYT HEINS OLENC EOFOF FICEA NDTHE SPURN STHAT PATIE NTMER ITOFT HUNWO RTHYT AKESW HENHE HIMSE LFMIG HTHIS QUIET USMAK EWITH ABARE BODKI NWHOW OULDF ARDEL SBEAR TOGRU NTAND SWEAT UNDER AWEAR YLIFE BUTTH ATTHE DREAD OFSOM ETHIN GAFTE RDEAT HTHEU NDISC OVERE DCOUN TRYFR OMWHO SEBOU RNNOT RAVEL LERRE TURNS PUZZL ESTHE WILLA NDMAK ESUSR ATHER BEART HOSEI LLSWE HAVET HANFL YTOOT HERST HATWE KNOWN OTOFT HUSCO NSCIE NCEDO ESMAK ECOWA RDSOF USALL ANDTH USTHE NATIV EHUEO FRESO LUTIO NISSI CKLIE DOERW ITHTH EPALE CASTO FTHOU GHTAN DENTE RPRIS EOFGR EATPI THAND MOMEN TWITH THISR EGARD THEIR CURRE NTSTU RNAWR YANDL OSETH ENAME OFACT IONSO FTYOU NOWTH EFAIR OPHEL IANYM PHINT HYORI SONSB EALLM YSINS REMEM BERED
Nim
import strutils
proc encrypt(msg, key: string): string =
var pos = 0
for c in msg:
if c in Letters:
result.add chr(((ord(key[pos]) + ord(c.toUpperAscii)) mod 26) + ord('A'))
pos = (pos + 1) mod key.len
proc decrypt(msg, key: string): string =
var pos = 0
for c in msg:
result.add chr(((26 + ord(c) - ord(key[pos])) mod 26) + ord('A'))
pos = (pos + 1) mod key.len
const text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
const key = "VIGENERECIPHER"
let encr = encrypt(text, key)
let decr = decrypt(encr, key)
echo text
echo encr
echo decr
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Objeck
bundle Default {
class VigenereCipher {
function : Main(args : String[]) ~ Nil {
key := "VIGENERECIPHER";
ori := "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
enc := encrypt(ori, key);
IO.Console->Print("encrypt: ")->PrintLine(enc);
IO.Console->Print("decrypt: ")->PrintLine(decrypt(enc, key));
}
function : native : encrypt(text : String, key : String) ~ String {
res := "";
text := text->ToUpper();
j := 0;
each(i : text) {
c := text->Get(i);
if(c >= 'A' & c <= 'Z') {
res->Append(((c + key->Get(j) - 2 * 'A') % 26 + 'A')->As(Char));
j += 1;
j := j % key->Size();
};
};
return res;
}
function : native : decrypt(text : String, key : String) ~ String {
res := "";
text := text->ToUpper();
j := 0;
each(i : text) {
c := text->Get(i);
if(c >= 'A' & c <= 'Z') {
res->Append(((c - key->Get(j) + 26) % 26 + 'A')->As(Char));
j += 1;
j := j % key->Size();
};
};
return res;
}
}
}
encrypt: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY decrypt: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
OCaml
let cipher src key crypt =
let str = String.uppercase src in
let key = String.uppercase key in
(* strip out non-letters *)
let len = String.length str in
let rec aux i j =
if j >= len then String.sub str 0 i else
if str.[j] >= 'A' && str.[j] <= 'Z'
then (str.[i] <- str.[j]; aux (succ i) (succ j))
else aux i (succ j)
in
let res = aux 0 0 in
let slen = String.length res in
let klen = String.length key in
let d = int_of_char in
let f =
if crypt
then fun i -> d res.[i] - d 'A' + d key.[i mod klen] - d 'A'
else fun i -> d res.[i] - d key.[i mod klen] + 26
in
for i = 0 to pred slen do
res.[i] <- char_of_int (d 'A' + (f i) mod 26)
done;
(res)
let () =
let str = "Beware the Jabberwock, my son! The jaws that bite, \
the claws that catch!" in
let key = "VIGENERECIPHER" in
let cod = cipher str key true in
let dec = cipher cod key false in
Printf.printf "Text: %s\n" str;
Printf.printf "key: %s\n" key;
Printf.printf "Code: %s\n" cod;
Printf.printf "Back: %s\n" dec;
;;
Run:
$ ocaml vigenere_cipher.ml Text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! key: VIGENERECIPHER Code: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Back: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Updated version by User:Vanyamil
This is a custom, more functional version of the existing solution, due to OCaml 4.05's unsafe-string compatibility mode
(* Task : Vigenère_cipher *)
(* This is a custom, more functional version of an existing solution,
due to OCaml 4.05's unsafe-string compatibility mode:
https://ocaml.org/api/String.html
*)
(*** Helpers ***)
(* Verbose type abbreviation *)
type key = string
(* Rotate a single uppercase letter *)
let ascii_caesar_shift : bool -> char -> char -> char =
let min_range = Char.code 'A' in
let max_range = Char.code 'Z' in
(* aka 26 but this code can be adapted to larger ranges, such as the ASCII printable range (codes 32 to 126). *)
let range_len = max_range - min_range + 1 in
let actual_fun (dir : bool) (c1 : char) (c2 : char) : char =
let n1 = Char.code c1 in
let n2 = Char.code c2 - min_range in
let sum = (if dir then (+) else (-)) n1 n2 in
( (* Effectively mod function, but simplified and works on negatives. *)
if sum > max_range
then sum - range_len
else if sum < min_range
then sum + range_len
else sum
) |> Char.chr
in
actual_fun
(* Remove non-letters and uppercase *)
let ascii_upper_letters_only (s : string) : string =
let slen = String.length s in
(* Make a list of escaped uppercase letter chars *)
let rec toLetterList sidx acc =
if sidx >= slen
then List.rev acc
else
let c = s.[sidx] in
if c >= 'A' && c <= 'Z'
then toLetterList (sidx + 1) ((c |> Char.escaped) :: acc)
else if c >= 'a' && c <= 'z'
then toLetterList (sidx + 1) ((c |> Char.uppercase_ascii |> Char.escaped) :: acc)
else toLetterList (sidx + 1) acc
in
toLetterList 0 [] |> String.concat ""
(*** Actual task at hand ***)
let vig_crypt (dir : bool) (key : key) (message : string) : string =
let message = ascii_upper_letters_only message in
let key = ascii_upper_letters_only key in
let klen = String.length key in
let aux idx c =
let kidx = idx mod klen in
let e = ascii_caesar_shift dir c key.[kidx] in
e
in
String.mapi aux message
let encrypt : key -> string -> string = vig_crypt true
let decrypt : key -> string -> string = vig_crypt false
(*** Output ***)
let () =
let str = "Beware the Jabberwock, my son! The jaws that bite, \
the claws that catch!" in
let key = "VIGENERECIPHER" in
let ct = encrypt key str in
let pt = decrypt key ct in
Printf.printf "Text: %s\n" str;
Printf.printf "Key: %s\n" key;
Printf.printf "Code: %s\n" ct;
Printf.printf "Back: %s\n" pt
;;
- Output:
Text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Key: VIGENERECIPHER Code: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Back: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
ooRexx
A reworking of the NetRexx version using Open Object Rexx but shouldn't take much to translate to Classic Rexx.
/* Rexx */
Do
alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
key = 'LEMON'
pt = 'Attack at dawn!'
Call test key, pt
key = 'N'
Call test key, pt
key = 'B'
Call test key, pt
pt = alpha
key = 'A'
Call test key, pt
pt = sampledata()
key = 'Hamlet; Prince of Denmark'
Call test key, pt
Return
End
Exit
vigenere:
Procedure Expose alpha
Do
Parse upper Arg meth, key, text
Select
When 'ENCIPHER'~abbrev(meth, 1) = 1 then df = 1
When 'DECIPHER'~abbrev(meth, 1) = 1 then df = -1
Otherwise Do
Say meth 'invalid. Must be "ENCIPHER" or "DECIPHER"'
Exit
End
End
text = stringscrubber(text)
key = stringscrubber(key)
code = ''
Do l_ = 1 to text~length()
M = alpha~pos(text~substr(l_, 1)) - 1
k_ = (l_ - 1) // key~length()
K = alpha~pos(key~substr(k_ + 1, 1)) - 1
C = mod((M + K * df), alpha~length())
C = alpha~substr(C + 1, 1)
code = code || C
End l_
Return code
Return
End
Exit
vigenere_encipher:
Procedure Expose alpha
Do
Parse upper Arg key, plaintext
Return vigenere('ENCIPHER', key, plaintext)
End
Exit
vigenere_decipher:
Procedure Expose alpha
Do
Parse upper Arg key, ciphertext
Return vigenere('DECIPHER', key, ciphertext)
End
Exit
mod:
Procedure
Do
Parse Arg N, D
Return (D + (N // D)) // D
End
Exit
stringscrubber:
Procedure Expose alpha
Do
Parse upper Arg cleanup
cleanup = cleanup~space(0)
Do label f_ forever
x_ = cleanup~verify(alpha)
If x_ = 0 then Leave f_
cleanup = cleanup~changestr(cleanup~substr(x_, 1), '')
end f_
Return cleanup
End
Exit
test:
Procedure Expose alpha
Do
Parse Arg key, pt
ct = vigenere_encipher(key, pt)
Call display ct
dt = vigenere_decipher(key, ct)
Call display dt
Return
End
Exit
display:
Procedure
Do
Parse Arg text
line = ''
o_ = 0
Do c_ = 1 to text~length()
b_ = o_ // 5
o_ = o_ + 1
If b_ = 0 then line = line' '
line = line || text~substr(c_, 1)
End c_
Say '....+....|'~copies(8)
Do label l_ forever
Parse Var line w1 w2 w3 w4 w5 w6 W7 w8 w9 w10 w11 w12 line
pline = w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12
Say pline~strip()
If line~strip()~length() = 0 then Leave l_
End l_
Say
Return
End
Exit
sampledata:
Procedure
Do
NL = '0a'x
X = 0
antic_disposition. = ''
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "To be, or not to be--that is the question:"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "Whether 'tis nobler in the mind to suffer"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "The slings and arrows of outrageous fortune"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "Or to take arms against a sea of troubles"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "And by opposing end them. To die, to sleep--"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "No more--and by a sleep to say we end"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "The heartache, and the thousand natural shocks"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "That flesh is heir to. 'Tis a consummation"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "Devoutly to be wished. To die, to sleep--"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "To sleep--perchance to dream: ay, there's the rub,"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "For in that sleep of death what dreams may come"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "When we have shuffled off this mortal coil,"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "Must give us pause. There's the respect"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "That makes calamity of so long life."
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "For who would bear the whips and scorns of time,"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "Th' oppressor's wrong, the proud man's contumely"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "The pangs of despised love, the law's delay,"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "The insolence of office, and the spurns"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "That patient merit of th' unworthy takes,"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "When he himself might his quietus make"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "With a bare bodkin? Who would fardels bear,"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "To grunt and sweat under a weary life,"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "But that the dread of something after death,"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "The undiscovered country, from whose bourn"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "No traveller returns, puzzles the will,"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "And makes us rather bear those ills we have"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "Than fly to others that we know not of?"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "Thus conscience does make cowards of us all,"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "And thus the native hue of resolution"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "Is sicklied o'er with the pale cast of thought,"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "And enterprise of great pith and moment"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "With this regard their currents turn awry"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "And lose the name of action. -- Soft you now,"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "The fair Ophelia! -- Nymph, in thy orisons"
X = X + 1; antic_disposition.0 = X; antic_disposition.X = "Be all my sins remembered."
melancholy_dane = ''
Do l_ = 1 for antic_disposition.0
melancholy_dane = melancholy_dane || antic_disposition.l_ || NL
End l_
Return melancholy_dane
End
Exit
- Output:
....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| LXFOP VEFRN HR ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| ATTAC KATDA WN ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| NGGNP XNGQN JA ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| ATTAC KATDA WN ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| BUUBD LBUEB XO ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| ATTAC KATDA WN ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| ABCDE FGHIJ KLMNO PQRST UVWXY Z ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| ABCDE FGHIJ KLMNO PQRST UVWXY Z ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| AONPS KCFBG QFSYK EGUSK RLQGP WMXFV JJIHM HVGUS EYILQ CMGIY MZKRR YRWHR FVBAH QDPBC XANPH OWUSJ EOWYB TDLKX DLASQ VHZQI BDTFD HKQLV FHRON KRGYD WRMOW DYOGM PXHRV QDCCU SSFUN XOUDF SIFIF LVGXC XOIRB NFWVR QLRWQ PIFNI SUWSF MYNOL NPELX WVIEV EQMHE APTYO AHAFW TCUVN VYFFO WUACB CAHME JETJP VULSN UXBFI JKJOZ DYFBR BVQRR JYSHF LPDVB QHMLW VLGQH WJWSF XEVZA OEWIX EGMEE LOSFI GADIO HMMJX ATIMF VLSWX FSARZ XAHME WETVX BHHSF WLJTA KNYEM XWFPP KBOIK MHRJQ HRFLS TFJYA VLBHJ HMLWZ ARKKS CATPF JJBTK ZSZVT NGSVD OEDPW MWVZR UTSHW XUMTD KREEN EEPDQ GASTX RPBZG CSMER ZVPWF EBWPR GHEEF HVGOI BDEGS JKBTR GTIXV YEKRV PBCIL HFZFY VCSJX UQPIY BDYLR LRFVG WQSQB XUQPR XNSAQ HXHGQ FGHZT YIGTE CKDSP PPTNK PRKRG TOIAO EFPVF RTGXP ELGJI GUXVA ETYKA PMEMX CKURT MHTIX UGNNY YTTJX TZVAJ JIBMH LVYSV VMMUR LMWZA DWMSY XWZMK VGPTT LFTGV JBFOW SZLBI OLVKF MCHXA JJRCV HTJVH ZTRXK SIPEM JELRT EKJDV LXIWO IUFEL TIKPR FVSFG SSEOD OAHUY KTUKM EFIOY KXUQU ENPSO ZZXGV LPQYB YUCSD ODGOO EPFHJ IVAQX FFYIY XEIBL TGCRL ELHMN IGYKI JULCK UDYLO XHLAE CXVJU FRMRK RVSQT PEHNM UCZSY KEARL PDVOF SIKHK PNVAS PQSJZ OKYMT TFWVD EAPKI BHHHB QSDKR EOZAT GUABH YGFOP NZDKR BSFSI GPKQI GLIJR JEQSF VBTUZ RBHJQ PMPWJ GSRDW ZDOTT PTTAV KNUXC KWLBG GYDHN PPRMT IXEKW STIKE QAKZP TTLRW BFURP XKNWL GTIJB LGMCH MWVQE EYFWH RGETL BUAIC CTCUT BUIHM HRNYE FPHCF TSGHF NGASI SRAGT EWKPR AALXA ZIAAQ DMLRG TYFBP SAYWU TRTYO CGNQW EQMVW IEDPH ....+....|....+....|....+....|....+....|....+....|....+....|....+....|....+....| TOBEO RNOTT OBETH ATIST HEQUE STION WHETH ERTIS NOBLE RINTH EMIND TOSUF FERTH ESLIN GSAND ARROW SOFOU TRAGE OUSFO RTUNE ORTOT AKEAR MSAGA INSTA SEAOF TROUB LESAN DBYOP POSIN GENDT HEMTO DIETO SLEEP NOMOR EANDB YASLE EPTOS AYWEE NDTHE HEART ACHEA NDTHE THOUS ANDNA TURAL SHOCK STHAT FLESH ISHEI RTOTI SACON SUMMA TIOND EVOUT LYTOB EWISH EDTOD IETOS LEEPT OSLEE PPERC HANCE TODRE AMAYT HERES THERU BFORI NTHAT SLEEP OFDEA THWHA TDREA MSMAY COMEW HENWE HAVES HUFFL EDOFF THISM ORTAL COILM USTGI VEUSP AUSET HERES THERE SPECT THATM AKESC ALAMI TYOFS OLONG LIFEF ORWHO WOULD BEART HEWHI PSAND SCORN SOFTI METHO PPRES SORSW RONGT HEPRO UDMAN SCONT UMELY THEPA NGSOF DESPI SEDLO VETHE LAWSD ELAYT HEINS OLENC EOFOF FICEA NDTHE SPURN STHAT PATIE NTMER ITOFT HUNWO RTHYT AKESW HENHE HIMSE LFMIG HTHIS QUIET USMAK EWITH ABARE BODKI NWHOW OULDF ARDEL SBEAR TOGRU NTAND SWEAT UNDER AWEAR YLIFE BUTTH ATTHE DREAD OFSOM ETHIN GAFTE RDEAT HTHEU NDISC OVERE DCOUN TRYFR OMWHO SEBOU RNNOT RAVEL LERRE TURNS PUZZL ESTHE WILLA NDMAK ESUSR ATHER BEART HOSEI LLSWE HAVET HANFL YTOOT HERST HATWE KNOWN OTOFT HUSCO NSCIE NCEDO ESMAK ECOWA RDSOF USALL ANDTH USTHE NATIV EHUEO FRESO LUTIO NISSI CKLIE DOERW ITHTH EPALE CASTO FTHOU GHTAN DENTE RPRIS EOFGR EATPI THAND MOMEN TWITH THISR EGARD THEIR CURRE NTSTU RNAWR YANDL OSETH ENAME OFACT IONSO FTYOU NOWTH EFAIR OPHEL IANYM PHINT HYORI SONSB EALLM YSINS REMEM BERED
Pascal
// The Vigenere cipher in reasonably standard Pascal
// <no library functions: all conversions hand-coded>
PROGRAM Vigenere;
// get a letter's alphabetic position (A=0)
FUNCTION letternum(letter: CHAR): BYTE;
BEGIN
letternum := (ord(letter)-ord('A'));
END;
// convert a character to uppercase
FUNCTION uch(ch: CHAR): CHAR;
BEGIN
uch := ch;
IF ch IN ['a'..'z'] THEN
uch := chr(ord(ch) AND $5F);
END;
// convert a string to uppercase
FUNCTION ucase(str: STRING): STRING;
VAR i: BYTE;
BEGIN
ucase := '';
FOR i := 1 TO Length(str) DO
ucase := ucase + uch(str[i]);
END;
// construct a Vigenere-compatible string:
// uppercase; no spaces or punctuation.
FUNCTION vstr(pt: STRING): STRING;
VAR c: Cardinal;
s: STRING;
BEGIN
vstr:= '';
s := ucase(pt);
FOR c := 1 TO Length(s) DO BEGIN
IF s[c] IN ['A'..'Z'] THEN
vstr += s[c];
END;
END;
// construct a repeating Vigenere key
FUNCTION vkey(pt, key: STRING): STRING;
VAR c,n: Cardinal;
k : STRING;
BEGIN
k := vstr(key);
vkey := '';
FOR c := 1 TO Length(pt) DO BEGIN
n := c mod Length(k);
IF n>0 THEN vkey += k[n] ELSE vkey += k[Length(k)];
END;
END;
// Vigenere encipher
FUNCTION enVig(pt,key:STRING): STRING;
VAR ct: STRING;
c,n : Cardinal;
BEGIN
ct := pt;
FOR c := 1 TO Length(pt) DO BEGIN
n := letternum(pt[c])+letternum(key[c]);
n := n mod 26;
ct[c]:=chr(ord('A')+n);
END;
enVig := ct;
END;
// Vigenere decipher
FUNCTION deVig(ct,key:STRING): STRING;
VAR pt : STRING;
c,n : INTEGER;
BEGIN
pt := ct;
FOR c := 1 TO Length(ct) DO BEGIN
n := letternum(ct[c])-letternum(key[c]);
IF n<0 THEN n:=26+n;
pt[c]:=chr(ord('A')+n);
END;
deVig := pt;
END;
VAR key: STRING = 'Vigenere cipher';
msg: STRING = 'Beware the Jabberwock! The jaws that bite, the claws that catch!';
vtx: STRING = '';
ctx: STRING = '';
ptx: STRING = '';
BEGIN
// make Vigenere-compatible
vtx := vstr(msg);
key := vkey(vtx,key);
// Vigenere encipher / decipher
ctx := enVig(vtx,key);
ptx := deVig(ctx,key);
// display results
Writeln('Message : ',msg);
Writeln('Plaintext : ',vtx);
Writeln('Key : ',key);
Writeln('Ciphertext : ',ctx);
Writeln('Plaintext : ',ptx);
END.
- Output:
Message : Beware the Jabberwock! The jaws that bite, the claws that catch! Plaintext : BEWARETHEJABBERWOCKTHEJAWSTHATBITETHECLAWSTHATCATCH Key : VIGENERECIPHERVIGENERECIPHERVIGENERECIPHERVIGENEREC Ciphertext : WMCEEIKLGRPIFVMEUGXXYILILZXYVBHMGIKLGKAHAJOPGXPEKGJ Plaintext : BEWARETHEJABBERWOCKTHEJAWSTHATBITETHECLAWSTHATCATCH
Perl
if( @ARGV != 3 ){
printHelp();
}
# translate to upper-case, remove anything else
map( (tr/a-z/A-Z/, s/[^A-Z]//g), @ARGV );
my $cipher_decipher = $ARGV[ 0 ];
if( $cipher_decipher !~ /ENC|DEC/ ){
printHelp(); # user should say what to do
}
print "Key: " . (my $key = $ARGV[ 2 ]) . "\n";
if( $cipher_decipher =~ /ENC/ ){
print "Plain-text: " . (my $plain = $ARGV[ 1 ]) . "\n";
print "Encrypted: " . Vigenere( 1, $key, $plain ) . "\n";
}elsif( $cipher_decipher =~ /DEC/ ){
print "Cipher-text: " . (my $cipher = $ARGV[ 1 ]) . "\n";
print "Decrypted: " . Vigenere( -1, $key, $cipher ) . "\n";
}
sub printHelp{
print "Usage:\n" .
"Encrypting:\n perl cipher.pl ENC (plain text) (key)\n" .
"Decrypting:\n perl cipher.pl DEC (cipher text) (key)\n";
exit -1;
}
sub Vigenere{
my ($direction, $key, $text) = @_;
for( my $count = 0; $count < length $text; $count ++ ){
$key_offset = $direction * ord substr( $key, $count % length $key, 1);
$char_offset = ord substr( $text, $count, 1 );
$cipher .= chr 65 + ((($char_offset % 26) + ($key_offset % 26)) % 26);
# 65 is the ASCII character code for 'A'
}
return $cipher;
}
Demonstration:
$ perl cipher.pl ENC 'Beware the Jabberwock, my son! The jaws that bite, the claws that catch!' VIGENERECIPHER Key: VIGENERECIPHER Plain-text: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY $ perl cipher.pl DEC WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY VIGENERECIPHER Key: VIGENERECIPHER Cipher-text: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH $ perl cipher.pl FOO WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY VIGENERECIPHER Usage: Encrypting: perl cipher.pl ENC (plain text) (key) Decrypting: perl cipher.pl DEC (cipher text) (key)
Phix
with javascript_semantics constant ENCRYPT = +1, DECRYPT = -1 function Vigenere(string s, key, integer mode) string res = "" integer k = 1, ch s = upper(s) for i=1 to length(s) do ch = s[i] if ch>='A' and ch<='Z' then res &= 'A'+mod(ch+mode*(key[k]+26),26) k = mod(k,length(key))+1 end if end for return res end function constant key = "LEMON", s = "ATTACK AT DAWN", e = Vigenere(s,key,ENCRYPT), d = Vigenere(e,key,DECRYPT) printf(1,"Original: %s\nEncrypted: %s\nDecrypted: %s\n",{s,e,d})
- Output:
Original: ATTACK AT DAWN Encrypted: LXFOPVEFRNHR Decrypted: ATTACKATDAWN
PHP
<?php
$str = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
$key = "VIGENERECIPHER";
printf("Text: %s\n", $str);
printf("key: %s\n", $key);
$cod = encipher($str, $key, true); printf("Code: %s\n", $cod);
$dec = encipher($cod, $key, false); printf("Back: %s\n", $dec);
function encipher($src, $key, $is_encode)
{
$key = strtoupper($key);
$src = strtoupper($src);
$dest = '';
/* strip out non-letters */
for($i = 0; $i <= strlen($src); $i++) {
$char = substr($src, $i, 1);
if(ctype_upper($char)) {
$dest .= $char;
}
}
for($i = 0; $i <= strlen($dest); $i++) {
$char = substr($dest, $i, 1);
if(!ctype_upper($char)) {
continue;
}
$dest = substr_replace($dest,
chr (
ord('A') +
($is_encode
? ord($char) - ord('A') + ord($key[$i % strlen($key)]) - ord('A')
: ord($char) - ord($key[$i % strlen($key)]) + 26
) % 26
)
, $i, 1);
}
return $dest;
}
?>
- Output:
Text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! key: VIGENERECIPHER Code: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Back: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
PicoLisp
(de vigenereKey (Str)
(extract
'((C)
(when (>= "Z" (uppc C) "A")
(- (char (uppc C)) 65) ) )
(chop Str) ) )
(de vigenereEncrypt (Str Key)
(pack
(mapcar
'((C K)
(char (+ 65 (% (+ C K) 26))) )
(vigenereKey Str)
(apply circ (vigenereKey Key)) ) ) )
(de vigenereDecrypt (Str Key)
(pack
(mapcar
'((C K)
(char (+ 65 (% (+ 26 (- C K)) 26))) )
(vigenereKey Str)
(apply circ (vigenereKey Key)) ) ) )
Test:
: (vigenereEncrypt "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!" "VIGENERECIPHER" ) -> "WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY" : (vigenereDecrypt @ "VIGENERECIPHER") -> "BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH"
PL/I
cypher: procedure options (main); /* 21 September 2012 */
declare t(26) character (26);
declare (i, j, k, L) fixed binary;
declare (original, encoded, coder) character (1000) varying initial ('');
declare cypher character (30) varying;
declare (co, ct, cc) character (1);
/* Set up cypher table. */
t(1) = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
do i = 2 to 26;
t(i) = substr(t(i-1), 2, 25) || substr(t(i-1), 1, 1);
end;
cypher = 'VIGILANCE';
original = 'Meet me on Tuesday evening at seven.';
put edit ('Message=', original) (a);
original = uppercase(original);
/* Create the cypher text, same length as original, or longer. */
coder = repeat(cypher, length(original)/length(cypher));
/* Encode the original message, character by character. */
/* Non-alphabetic characters are ignored. */
L = 0;
do i = 1 to length(original);
co = substr(original, i, 1);
j = index(t(1), co);
if j = 0 then iterate; /* Ignore non-alphabetic character */
L = L + 1;
ct = substr(coder, L, 1);
k = index(t(1), ct);
encoded = encoded || substr(t(j), k, 1);
end;
put skip data (encoded);
/* DECODING. */
put skip list ('Decoded=');
do i = 1 to length(encoded);
cc = substr(coder, i, 1);
j = index(t(1), cc);
k = index(t(j), substr(encoded, i, 1));
put edit (substr(t(1), k, 1) ) (a(1));
end;
end cypher;
- Output:
Message=Meet me on Tuesday evening at seven. ENCODED='HMKBXEBPXPMYLLYRXIIQTOLTFGZZV'; Decoded= MEETMEONTUESDAYEVENINGATSEVEN
PowerShell
# Author: D. Cudnohufsky
function Get-VigenereCipher
{
Param
(
[Parameter(Mandatory=$true)]
[string] $Text,
[Parameter(Mandatory=$true)]
[string] $Key,
[switch] $Decode
)
begin
{
$map = [char]'A'..[char]'Z'
}
process
{
$Key = $Key -replace '[^a-zA-Z]',''
$Text = $Text -replace '[^a-zA-Z]',''
$keyChars = $Key.toUpper().ToCharArray()
$Chars = $Text.toUpper().ToCharArray()
function encode
{
param
(
$Char,
$keyChar,
$Alpha = [char]'A'..[char]'Z'
)
$charIndex = $Alpha.IndexOf([int]$Char)
$keyIndex = $Alpha.IndexOf([int]$keyChar)
$NewIndex = ($charIndex + $KeyIndex) - $Alpha.Length
$Alpha[$NewIndex]
}
function decode
{
param
(
$Char,
$keyChar,
$Alpha = [char]'A'..[char]'Z'
)
$charIndex = $Alpha.IndexOf([int]$Char)
$keyIndex = $Alpha.IndexOf([int]$keyChar)
$int = $charIndex - $keyIndex
if ($int -lt 0) { $NewIndex = $int + $Alpha.Length }
else { $NewIndex = $int }
$Alpha[$NewIndex]
}
while ( $keyChars.Length -lt $Chars.Length )
{
$keyChars = $keyChars + $keyChars
}
for ( $i = 0; $i -lt $Chars.Length; $i++ )
{
if ( [int]$Chars[$i] -in $map -and [int]$keyChars[$i] -in $map )
{
if ($Decode) {$Chars[$i] = decode $Chars[$i] $keyChars[$i] $map}
else {$Chars[$i] = encode $Chars[$i] $keyChars[$i] $map}
$Chars[$i] = [char]$Chars[$i]
[string]$OutText += $Chars[$i]
}
}
$OutText
$OutText = $null
}
}
Usage examples:
Encode: PS C:\> Get-VigenereCipher 'We attack at dawn.' 'lemon' HIMHGLGWOGOEIB Decode: PS C:\> Get-VigenereCipher 'HIMHGLGWOGOEIB' 'lemon' -Decode WEATTACKATDAWN
PureBasic
Procedure prepString(text.s, Array letters(1))
;convert characters to an ordinal (0-25) and remove non-alphabetic characters,
;returns dimension size of result array letters()
Protected *letter.Character, index
Dim letters(Len(text))
text = UCase(text)
*letter = @text
While *letter\c
Select *letter\c
Case 'A' To 'Z'
letters(index) = *letter\c - 65
index + 1
EndSelect
*letter + SizeOf(Character)
Wend
If index > 0
Redim letters(index - 1)
EndIf
ProcedureReturn index - 1
EndProcedure
Procedure.s VC_encrypt(text.s, keyText.s, reverse = 0)
;if reverse <> 0 then reverse the key (decrypt)
Protected *letter.Character
Dim text(0)
Dim keyText(0)
If prepString(text, text()) < 0 Or prepString(keyText, keyText()) < 0: ProcedureReturn: EndIf ;exit, nothing to work with
Protected i, keyLength = ArraySize(keyText())
If reverse
For i = 0 To keyLength
keyText(i) = 26 - keyText(i)
Next
EndIf
Protected textLength = ArraySize(text()) ;zero-based length
Protected result.s = Space(textLength + 1), *resultLetter.Character
keyLength + 1 ;convert from zero-based to one-based count
*resultLetter = @result
For i = 0 To textLength
*resultLetter\c = ((text(i) + keyText(i % keyLength)) % 26) + 65
*resultLetter + SizeOf(Character)
Next
ProcedureReturn result
EndProcedure
Procedure.s VC_decrypt(cypherText.s, keyText.s)
ProcedureReturn VC_encrypt(cypherText, keyText.s, 1)
EndProcedure
If OpenConsole()
Define VignereCipher.s, plainText.s, encryptedText.s, decryptedText.s
VignereCipher.s = "VIGNERECIPHER"
plainText = "The quick brown fox jumped over the lazy dogs.": PrintN(RSet("Plain text = ", 17) + #DQUOTE$ + plainText + #DQUOTE$)
encryptedText = VC_encrypt(plainText, VignereCipher): PrintN(RSet("Encrypted text = ", 17) + #DQUOTE$ + encryptedText + #DQUOTE$)
decryptedText = VC_decrypt(encryptedText, VignereCipher): PrintN(RSet("Decrypted text = ", 17) + #DQUOTE$ + decryptedText + #DQUOTE$)
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf
- Output:
Plain text = "The quick brown fox jumped over the lazy dogs." Encrypted text = "OPKDYZGMJGVAEAWDWYDTGLDCIIOPKYEQCFWVZ" Decrypted text = "THEQUICKBROWNFOXJUMPEDOVERTHELAZYDOGS"
Python
'''Vigenere encryption and decryption'''
from itertools import starmap, cycle
def encrypt(message, key):
'''Vigenere encryption of message using key.'''
# Converted to uppercase.
# Non-alpha characters stripped out.
message = filter(str.isalpha, message.upper())
def enc(c, k):
'''Single letter encryption.'''
return chr(((ord(k) + ord(c) - 2 * ord('A')) % 26) + ord('A'))
return ''.join(starmap(enc, zip(message, cycle(key))))
def decrypt(message, key):
'''Vigenere decryption of message using key.'''
def dec(c, k):
'''Single letter decryption.'''
return chr(((ord(c) - ord(k) - 2 * ord('A')) % 26) + ord('A'))
return ''.join(starmap(dec, zip(message, cycle(key))))
def main():
'''Demonstration'''
text = 'Beware the Jabberwock, my son! The jaws that bite, ' + (
'the claws that catch!'
)
key = 'VIGENERECIPHER'
encr = encrypt(text, key)
decr = decrypt(encr, key)
print(text)
print(encr)
print(decr)
if __name__ == '__main__':
main()
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Quackery
[ [] swap witheach
[ upper
dup char A char Z 1+ within
iff join else drop ] ] is onlycaps ( $ --> $ )
[ onlycaps
[] swap witheach
[ char A - join ] ] is cipherdisk ( $ --> [ )
[ [] swap witheach
[ 26 swap - join ] ] is deciphering ( [ --> [ )
[ behead tuck join swap ] is nextkey ( [ --> [ n )
[ dip nextkey + dup
char Z > if [ 26 - ] ] is encryptchar ( [ c --> [ c )
[ $ "" swap rot
onlycaps witheach
[ encryptchar
swap dip join ]
drop ] is vigenere ( $ [ --> $ )
[ cipherdisk vigenere ] is encrypt ( $ $ --> $ )
[ cipherdisk deciphering vigenere ] is decrypt ( $ $ --> $ )
$ "If you reveal your secrets to the wind, you should "
$ "not blame the wind for revealing them to the trees." join
say "Encrypted: " $ "Kahlil Gibran" encrypt dup echo$ cr
say "Decrypted: " $ "Kahlil Gibran" decrypt echo$
- Output:
Encrypted: SFFZCCKDFRLLYUYDMNXMUJTBDHLHQYJGPLSUYUSOVZZJMRMRDHLHQYJNPIRRFEHWQYMBIVMGYTOPBCKMT Decrypted: IFYOUREVEALYOURSECRETSTOTHEWINDYOUSHOULDNOTBLAMETHEWINDFORREVEALINGTHEMTOTHETREES
R
mod1 = function(v, n)
# mod1(1:20, 6) => 1 2 3 4 5 6 1 2 3 4 5 6 1 2 3 4 5 6 1 2
((v - 1) %% n) + 1
str2ints = function(s)
as.integer(Filter(Negate(is.na),
factor(levels = LETTERS, strsplit(toupper(s), "")[[1]])))
vigen = function(input, key, decrypt = F)
{input = str2ints(input)
key = rep(str2ints(key), len = length(input)) - 1
paste(collapse = "", LETTERS[
mod1(input + (if (decrypt) -1 else 1)*key, length(LETTERS))])}
message(vigen("Beware the Jabberwock, my son! The jaws that bite, the claws that catch!", "vigenerecipher"))
# WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY
message(vigen("WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY", "vigenerecipher", decrypt = T))
# BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Racket
#lang racket
(define chr integer->char)
(define ord char->integer)
(define (encrypt msg key)
(define cleaned
(list->string
(for/list ([c (string-upcase msg)]
#:when (char-alphabetic? c)) c)))
(list->string
(for/list ([c cleaned] [k (in-cycle key)])
(chr (+ (modulo (+ (ord c) (ord k)) 26) (ord #\A))))))
(define (decrypt msg key)
(list->string
(for/list ([c msg] [k (in-cycle key)])
(chr (+ (modulo (- (ord c) (ord k)) 26) (ord #\A))))))
(decrypt (encrypt "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
"VIGENERECIPHER")
"VIGENERECIPHER")
- Output:
"BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH"
Raku
(formerly Perl 6)
sub s2v ($s) { $s.uc.comb(/ <[ A..Z ]> /)».ord »-» 65 }
sub v2s (@v) { (@v »%» 26 »+» 65)».chr.join }
sub blacken ($red, $key) { v2s(s2v($red) »+» s2v($key)) }
sub redden ($blk, $key) { v2s(s2v($blk) »-» s2v($key)) }
my $red = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
my $key = "Vigenere Cipher!!!";
say $red;
say my $black = blacken($red, $key);
say redden($black, $key);
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
This is a natural job for hyperoperators, which can vectorize any operator. For infix operators the pointy end indicates which side to "dwim", repeating elements on that side until the other side runs out. In particular, repeating the key naturally falls out of this cyclic dwimmery, as does repeating the various constants to be applied with any of several operations to every element of the list. Factoring out the canonicalization and decanonicalization lets us see quite clearly that the only difference between encryption and decryptions is the sign of the vector addition/subtraction. Since hyperops are inherently parallelizable, this algorithm might run well in your GPU.
Red
note: this program is much longer than it needed to be - because i couldn't resist to add some more features to make it actually "useful" :-) So not only can u encrypt any character (because the crypted message will be base 64 encoded), but it also includes a Gui.
the Gui window has buttons to access the clipboard too - so u can get the original text from clipboard and put the crypted message back again. To execute it,simply download the latest red.exe (about 1,1 MB size! ) from red-lang.org. This program can also be compiled to an .exe (+ red runtime.dll ) by simply execute
red.exe -c vign1.red
or
red.exe -r vign1.red
which creates a single .exe file whithout the need for any .dll . should be working on windows , linux ( under wine ) and mac OS.
Red [needs: 'view]
CRLF: copy "^M^/" ;; constant for 0D 0A line feed
;;------------------------------------
crypt: func ["function to en- or decrypt message from textarea tx1"
/decrypt "decrypting switch/refinement" ][
;;------------------------------------
;; when decrypting we have to remove the superflous newlines
;; and undo the base64 encoding first ...
txt: either decrypt [ ;; message to en- or decrypt
s: copy tx1/text
;; newline could be single 0a byte or crlf sequence when copied from clipboard...
debase replace/all s either find s CRLF [CRLF ] [ newline ] ""
] [
tx1/text ;; plaintext message
]
txt: to-binary txt ;; handle message as binary
key: to-binary key1/text ;; handle key also as binary
bin: copy either decrypt [ "" ][ #{} ] ;; buffer for output
code: copy #{} ;; temp field to collect utf8 bytes when decrypting
;; loop over length of binary! message ...
repeat pos length? txt [
k: to-integer key/(1 + modulo pos length? key) ;; get corresponding key byte
c: to-integer txt/:pos ;; get integer value from message byte at position pos
either decrypt [ ;; decrypting ?
c: modulo ( 256 + c - k ) 256 ;; compute original byte value
case [
;; byte starting with 11.... ( >= 192 dec ) is utf8 startbyte
;; byte starting with 10... ( >= 128 dec) is utf8 follow up byte , below is single ascii byte
( c >= 192 ) or ( c < 128 ) [ ;; starting utf8 sequence byte or below 128 normal ascii ?
;; append last code to buffer, maybe normal ascii or utf8 sequence...
if not empty? code [ append bin to-char code ] ;; save previous code first
code: append copy #{} c ;; start new code
]
true [ append code c ] ;; otherwise utf8 follow up byte, append to startbyte
]
][
append bin modulo ( c + k ) 256 ;; encrypting , simply collect binary bytes
]
] ;; close repeat loop
either decrypt [ ;; collect utf-8 characters
append bin to-char code ;; append last code
tx2/text: to-string bin ;; create valid utf8 string when decrypting
][ ;; base64 encoding of crypted binary to get readable text string...
s: enbase copy bin ;; base 64 is default
while [40 < length? s ] [ ;; insert newlines for better "readability"
s: skip s either head? s [40][41] ;; ... every 40 characters
insert s newline
]
tx2/text: head s ;; reset s pointing to head again
]
]
;----------------------------------------------------------
; start of program
;----------------------------------------------------------
view layout [title "vigenere cyphre" ;Define nice GUI :- )
;----------------------------------------------------------
backdrop silver ;; define window background colour
text "message:" pad 99x1 button "get-clip" [tx1/text: read-clipboard]
;; code in brackets will be executed, when button is clicked:
button "clear" [tx1/text: copy "" ] return
tx1: area 330x80 "" return
text 25x20 "Key:" key1: field 290x20 "secretkey" return
button "crypt" [crypt ] button "decrypt" [crypt/decrypt ]
button "swap" [tx1/text: copy tx2/text tx2/text: copy "" ] return
text "de-/encrypted message:" pad 50x1 button "copy clip" [ write-clipboard tx2/text]
button "clear" [tx2/text: copy "" ] return
tx2: area 330x100 return
pad 270x1 button "Quit " [quit]
]
- Output:
the message
Beware the Jabberwock, my son! The jaws that bite, the claws that catch!
with key "VIGENERECIPHER" translates to
i6y8r7e3ZbextWiPs7irrLfFtLWwb2m9wWXFxbdo ZaKtt2Wtqse7Zca+qrtlsK7Gqm9pxLCqcrm1qLzBZcatpL1wq6bGubFo
decrypting returns the original message
Beware the Jabberwock, my son! The jaws that bite, the claws that catch!
REXX
uppercase text only
/*REXX program encrypts (and displays) uppercased text using the Vigenère cypher.*/
@.1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
L=length(@.1)
do j=2 to L; jm=j-1; q=@.jm
@.j=substr(q, 2, L - 1)left(q, 1)
end /*j*/
cypher = space('WHOOP DE DOO NO BIG DEAL HERE OR THERE', 0)
oMsg = 'People solve problems by trial and error; judgement helps pick the trial.'
oMsgU = oMsg; upper oMsgU
cypher_= copies(cypher, length(oMsg) % length(cypher) )
say ' original text =' oMsg
xMsg= Ncypher(oMsgU); say ' cyphered text =' xMsg
bMsg= Dcypher(xMsg) ; say 're-cyphered text =' bMsg
exit
/*──────────────────────────────────────────────────────────────────────────────────────*/
Ncypher: parse arg x; nMsg=; #=1 /*unsupported char? ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
do i=1 for length(x); j=pos(substr(x,i,1), @.1); if j==0 then iterate
nMsg=nMsg || substr(@.j, pos( substr( cypher_, #, 1), @.1), 1); #=#+1
end /*j*/
return nMsg
/*──────────────────────────────────────────────────────────────────────────────────────*/
Dcypher: parse arg x; dMsg=
do i=1 for length(x); j=pos(substr(cypher_, i, 1), @.1)
dMsg=dMsg || substr(@.1, pos( substr(x, i, 1), @.j), 1 )
end /*j*/
return dMsg
- output when using the default internal fields:
original text = People solve problems by trial and error; judgement helps pick the trial. cyphered text = LLCDAHWRZJRDSWHOIMDICKVWREHRUINYCFYXHJSARBUPKOTSAPGBXVVMYMRP re-cyphered text = PEOPLESOLVEPROBLEMSBYTRIALANDERRORJUDGEMENTHELPSPICKTHETRIAL
supports most characters
This version supports all characters on the IBM Model M keyboard, including blanks, but any other
characters can be added as long as they're viewable.
Additional characters can be added by simply appending them to the @.1 variable.
/*REXX program encrypts (and displays) most text using the Vigenère cypher. */
@abc= 'abcdefghijklmnopqrstuvwxyz'; @abcU=@abc; upper @abcU
@.1 = @abcU || @abc'0123456789~`!@#$%^&*()_-+={}|[]\:;<>?,./" '''
L=length(@.1)
do j=2 to length(@.1); jm=j - 1; q=@.jm
@.j=substr(q, 2, L - 1)left(q, 1)
end /*j*/
cypher = space('WHOOP DE DOO NO BIG DEAL HERE OR THERE', 0)
oMsg = 'Making things easy is just knowing the shortcuts. --- Gerard J. Schildberger'
cypher_= copies(cypher, length(oMsg) % length(cypher) )
say ' original text =' oMsg
xMsg= Ncypher(oMsg); say ' cyphered text =' xMsg
bMsg= Dcypher(xMsg); say 're-cyphered text =' bMsg
exit
/*──────────────────────────────────────────────────────────────────────────────────────*/
Ncypher: parse arg x; nMsg=; #=1 /*unsupported char? ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/
do i=1 for length(x); j=pos(substr(x,i,1), @.1); if j==0 then iterate
nMsg=nMsg || substr(@.j, pos( substr( cypher_, #, 1), @.1), 1); #=# + 1
end /*j*/
return nMsg
/*──────────────────────────────────────────────────────────────────────────────────────*/
Dcypher: parse arg x; dMsg=
do i=1 for length(x); j=pos(substr(cypher_, i, 1), @.1)
dMsg=dMsg || substr(@.1, pos( substr(x, i, 1), @.j), 1 )
end /*j*/
return dMsg
- output when using the default internal fields:
original text = Making things easy is just knowing the shortcuts. --- Gerard J. Schildberger cyphered text = ihyw2jCwvw0utGkdwyJpwPn89!Fo4s&p1uNwlhM6u2s1ixxsGF}"}MXxye8h/H?/QafgjbZcpecp re-cyphered text = Making things easy is just knowing the shortcuts. --- Gerard J. Schildberger
Ring
# Project : Vigenère cipher
key = "LEMON"
plaintext = "ATTACK AT DAWN"
ciphertext = encrypt(plaintext, key)
see "key = "+ key + nl
see "plaintext = " + plaintext + nl
see "ciphertext = " + ciphertext + nl
see "decrypted = " + decrypt(ciphertext, key) + nl
func encrypt(plain, key)
o = ""
k = 0
plain = fnupper(plain)
key = fnupper(key)
for i = 1 to len(plain)
n = ascii(plain[i])
if n >= 65 and n <= 90
o = o + char(65 + (n + ascii(key[k+1])) % 26)
k = (k + 1) % len(key)
ok
next
return o
func decrypt(cipher, key)
o = ""
k = 0
cipher = fnupper(cipher)
key = fnupper(key)
for i = 1 to len(cipher)
n = ascii(cipher[i])
o = o + char(65 + (n + 26 - ascii(key[k+1])) % 26)
k = (k + 1) % len(key)
next
return o
func fnupper(a)
for aa = 1 to len(a)
c = ascii(a[aa])
if c >= 97 and c <= 122
a[aa] = char(c-32)
ok
next
return a
Output:
key = LEMON plaintext = ATTACK AT DAWN ciphertext = LXFOPVEFRNHR decrypted = ATTACKATDAWN
RPL
As the encoding and decoding programs would differ by only one instruction (plus instead of minus), they have been merged into a single function that decodes if the input text is in uppercase only, and encodes otherwise. To encode a uppercase-only text, a space (or any punctuation sign) must be put somwehere.
≪ → key
≪ 1 CF { }
1 3 PICK SIZE FOR j
OVER j DUP SUB NUM
IF DUP 97 ≥ OVER 122 ≤ AND THEN 32 - END
IF DUP 65 ≥ OVER 90 ≤ AND THEN 65 - + ELSE 1 SF DROP END
NEXT
SWAP DROP ""
1 3 PICK SIZE FOR j
OVER j GET
key j 1 - key SIZE MOD 1 + DUP SUB NUM 64 -
IF 1 FC? THEN + ELSE - END
26 MOD 65 + CHR +
NEXT
SWAP DROP
≫ ≫ ‘VIGENERE’ STO
"Beware the Jabberwock!" VIGENERE DUP VIGENERE
- Output:
2: "FVPVDZBCIATWNZZRSTD" 1: "BEWARETHEJABBERWOCK"
Ruby
module VigenereCipher
BASE = 'A'.ord
SIZE = 'Z'.ord - BASE + 1
def encrypt(text, key)
crypt(text, key, :+)
end
def decrypt(text, key)
crypt(text, key, :-)
end
def crypt(text, key, dir)
text = text.upcase.gsub(/[^A-Z]/, '')
key_iterator = key.upcase.gsub(/[^A-Z]/, '').chars.map{|c| c.ord - BASE}.cycle
text.each_char.inject('') do |ciphertext, char|
offset = key_iterator.next
ciphertext << ((char.ord - BASE).send(dir, offset) % SIZE + BASE).chr
end
end
end
Demonstration:
include VigenereCipher
plaintext = 'Beware the Jabberwock, my son! The jaws that bite, the claws that catch!'
key = 'Vigenere cipher'
ciphertext = VigenereCipher.encrypt(plaintext, key)
recovered = VigenereCipher.decrypt(ciphertext, key)
puts "Original: #{plaintext}"
puts "Encrypted: #{ciphertext}"
puts "Decrypted: #{recovered}"
- Output:
Original: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Rust
use std::ascii::AsciiExt;
static A: u8 = 'A' as u8;
fn uppercase_and_filter(input: &str) -> Vec<u8> {
let alphabet = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
let mut result = Vec::new();
for c in input.chars() {
// Ignore anything that is not in our short list of chars. We can then safely cast to u8.
if alphabet.iter().any(|&x| x as char == c) {
result.push(c.to_ascii_uppercase() as u8);
}
}
return result;
}
fn vigenere(key: &str, text: &str, is_encoding: bool) -> String {
let key_bytes = uppercase_and_filter(key);
let text_bytes = uppercase_and_filter(text);
let mut result_bytes = Vec::new();
for (i, c) in text_bytes.iter().enumerate() {
let c2 = if is_encoding {
(c + key_bytes[i % key_bytes.len()] - 2 * A) % 26 + A
} else {
(c + 26 - key_bytes[i % key_bytes.len()]) % 26 + A
};
result_bytes.push(c2);
}
String::from_utf8(result_bytes).unwrap()
}
fn main() {
let text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
let key = "VIGENERECIPHER";
println!("Text: {}", text);
println!("Key: {}", key);
let encoded = vigenere(key, text, true);
println!("Code: {}", encoded);
let decoded = vigenere(key, &encoded, false);
println!("Back: {}", decoded);
}
Scala
Valid characters for messages: A through Z, zero, 1 to 9, and full-stop (.)
object Vigenere {
def encrypt(msg: String, key: String) : String = {
var result: String = ""
var j = 0
for (i <- 0 to msg.length - 1) {
val c = msg.charAt(i)
if (c >= 'A' && c <= 'Z') {
result += ((c + key.charAt(j) - 2 * 'A') % 26 + 'A').toChar
j = (j + 1) % key.length
}
}
return result
}
def decrypt(msg: String, key: String) : String = {
var result: String = ""
var j = 0
for (i <- 0 to msg.length - 1) {
val c = msg.charAt(i)
if (c >= 'A' && c <= 'Z') {
result += ((c - key.charAt(j) + 26) % 26 + 'A').toChar
j = (j + 1) % key.length
}
}
return result
}
}
println("Encrypt text ABC => " + Vigenere.encrypt("ABC", "KEY"))
println("Decrypt text KFA => " + Vigenere.decrypt("KFA", "KEY"))
- Output:
scala> Encrypt text ABC => KFA scala> Decrypt text KFA => ABC
Seed7
$ include "seed7_05.s7i";
const func string: vigenereCipher (in string: source, in var string: keyword) is func
result
var string: dest is "";
local
var char: ch is ' ';
var integer: index is 1;
var integer: shift is 0;
begin
keyword := upper(keyword);
for ch range source do
if ch in {'A' .. 'Z'} | {'a' .. 'z'} then
shift := ord(keyword[succ(pred(index) rem length(keyword))]) - ord('A');
dest &:= chr(ord('A') + (ord(upper(ch)) - ord('A') + shift) rem 26);
incr(index);
end if;
end for;
end func;
const func string: vigenereDecipher (in string: source, in var string: keyword) is func
result
var string: dest is "";
local
var char: ch is ' ';
var integer: index is 0;
var integer: shift is 0;
begin
keyword := upper(keyword);
for ch key index range source do
if ch in {'A' .. 'Z'} | {'a' .. 'z'} then
shift := ord(keyword[succ(pred(index) rem length(keyword))]) - ord('A');
dest &:= chr(ord('A') + (ord(upper(ch)) - ord('A') - shift) mod 26);
end if;
end for;
end func;
const proc: main is func
local
const string: input is "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
const string: keyword is "VIGENERECIPHER";
var string: encrypted is "";
var string: decrypted is "";
begin
writeln("Input: " <& input);
writeln("key: " <& keyword);
encrypted := vigenereCipher(input, keyword);
writeln("Encrypted: " <& encrypted);
decrypted := vigenereDecipher(encrypted, keyword);
writeln("Decrypted: " <& decrypted);
end func;
- Output:
Input: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! key: VIGENERECIPHER Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Sidef
func s2v(s) { s.uc.scan(/[A-Z]/).map{.ord} »-» 65 }
func v2s(v) { v »%» 26 »+» 65 -> map{.chr}.join }
func blacken (red, key) { v2s(s2v(red) »+« s2v(key)) }
func redden (blk, key) { v2s(s2v(blk) »-« s2v(key)) }
var red = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
var key = "Vigenere Cipher!!!"
say red
say (var black = blacken(red, key))
say redden(black, key)
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Smalltalk
in the following code, the cypher should consist of upper-case characters only. If that is not guaranteed, apply prep to it before passing it to encrypt/decrypt..
prep := [:s | s select:[:ch | ch isLetter] thenCollect:[:ch | ch asUppercase]].
encrypt := [:s :cypher | (prep value:s) keysAndValuesCollect:[:i :ch | ch rot:((cypher at:((i-1)\\key size+1))-$A) ]].
decrypt := [:s :cypher | (prep value:s) keysAndValuesCollect:[:i :ch | ch rot:26-((cypher at:((i-1)\\key size+1))-$A) ]].
Test:
plain := 'Beware the Jabberwock, my son! The jaws that bite, the claws that catch!'.
cypher := 'VIGENERECIPHER'.
crypted := encrypt value:plain value:cypher.
plain2 := decrypt value:crypted value:cypher.
crypted -> 'WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY'
plain2 -> 'BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH'
Swift
Can support a larger range of characters, if desired
public func convertToUnicodeScalars(
str: String,
minChar: UInt32,
maxChar: UInt32
) -> [UInt32] {
var scalars = [UInt32]()
for scalar in str.unicodeScalars {
let val = scalar.value
guard val >= minChar && val <= maxChar else {
continue
}
scalars.append(val)
}
return scalars
}
public struct Vigenere {
private let keyScalars: [UInt32]
private let smallestScalar: UInt32
private let largestScalar: UInt32
private let sizeAlphabet: UInt32
public init?(key: String, smallestCharacter: Character = "A", largestCharacter: Character = "Z") {
let smallScalars = smallestCharacter.unicodeScalars
let largeScalars = largestCharacter.unicodeScalars
guard smallScalars.count == 1, largeScalars.count == 1 else {
return nil
}
self.smallestScalar = smallScalars.first!.value
self.largestScalar = largeScalars.first!.value
self.sizeAlphabet = (largestScalar - smallestScalar) + 1
let scalars = convertToUnicodeScalars(str: key, minChar: smallestScalar, maxChar: largestScalar)
guard !scalars.isEmpty else {
return nil
}
self.keyScalars = scalars
}
public func decrypt(_ str: String) -> String? {
let txtBytes = convertToUnicodeScalars(str: str, minChar: smallestScalar, maxChar: largestScalar)
guard !txtBytes.isEmpty else {
return nil
}
var res = ""
for (i, c) in txtBytes.enumerated() where c >= smallestScalar && c <= largestScalar {
guard let char =
UnicodeScalar((c &+ sizeAlphabet &- keyScalars[i % keyScalars.count]) % sizeAlphabet &+ smallestScalar)
else {
return nil
}
res += String(char)
}
return res
}
public func encrypt(_ str: String) -> String? {
let txtBytes = convertToUnicodeScalars(str: str, minChar: smallestScalar, maxChar: largestScalar)
guard !txtBytes.isEmpty else {
return nil
}
var res = ""
for (i, c) in txtBytes.enumerated() where c >= smallestScalar && c <= largestScalar {
guard let char =
UnicodeScalar((c &+ keyScalars[i % keyScalars.count] &- 2 &* smallestScalar) % sizeAlphabet &+ smallestScalar)
else {
return nil
}
res += String(char)
}
return res
}
}
let text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
let key = "VIGENERECIPHER";
let cipher = Vigenere(key: key)!
print("Key: \(key)")
print("Plain Text: \(text)")
let encoded = cipher.encrypt(text.uppercased())!
print("Cipher Text: \(encoded)")
let decoded = cipher.decrypt(encoded)!
print("Decoded: \(decoded)")
print("\nLarger set:")
let key2 = "Vigenère cipher"
let text2 = "This is a ünicode string 😃"
let cipher2 = Vigenere(key: key2, smallestCharacter: " ", largestCharacter: "🛹")!
print("Key: \(key2)")
print("Plain Text: \(text2)")
let encoded2 = cipher2.encrypt(text2)!
print("Cipher Text: \(encoded2)")
let decoded2 = cipher2.decrypt(encoded2)!
print("Decoded: \(decoded2)")
- Output:
Key: VIGENERECIPHER Plain Text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Cipher Text: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decoded: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH Larger set: Key: Vigenère cipher Plain Text: This is a ünicode string 😃 Cipher Text: �±°¸nıÅeacŅ¾±¨Á�®g¸Âĺ»³gc🙌 Decoded: This is a ünicode string 😃
Tcl
package require Tcl 8.6
oo::class create Vigenere {
variable key
constructor {protoKey} {
foreach c [split $protoKey ""] {
if {[regexp {[A-Za-z]} $c]} {
lappend key [scan [string toupper $c] %c]
}
}
}
method encrypt {text} {
set out ""
set j 0
foreach c [split $text ""] {
if {[regexp {[^a-zA-Z]} $c]} continue
scan [string toupper $c] %c c
append out [format %c [expr {($c+[lindex $key $j]-130)%26+65}]]
set j [expr {($j+1) % [llength $key]}]
}
return $out
}
method decrypt {text} {
set out ""
set j 0
foreach c [split $text ""] {
if {[regexp {[^A-Z]} $c]} continue
scan $c %c c
append out [format %c [expr {($c-[lindex $key $j]+26)%26+65}]]
set j [expr {($j+1) % [llength $key]}]
}
return $out
}
}
Demonstrating:
set cypher [Vigenere new "Vigenere Cipher"]
set original "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
set encrypted [$cypher encrypt $original]
set decrypted [$cypher decrypt $encrypted]
puts $original
puts "Encrypted: $encrypted"
puts "Decrypted: $decrypted"
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
TXR
@(next :args)
@(do
(defun vig-op (plus-or-minus)
(op + #\A [mod [plus-or-minus (- @1 #\A) (- @2 #\A)] 26]))
(defun vig (msg key encrypt)
(mapcar (vig-op [if encrypt + -]) msg (repeat key))))
@(coll)@{key /[A-Za-z]/}@(end)
@(coll)@{msg /[A-Za-z]/}@(end)
@(cat key "")
@(filter :upcase key)
@(cat msg "")
@(filter :upcase msg)
@(bind encoded @(vig msg key t))
@(bind decoded @(vig msg key nil))
@(bind check @(vig encoded key nil))
@(output)
text: @msg
key: @key
enc: @encoded
dec: @decoded
check: @check
@(end)
Here, the TXR pattern language is used to scan letters out of two arguments, and convert them to upper case. The embedded TXR Lisp dialect handles the Vigenère logic, in just a few lines of code.
Lisp programmers may do a "double take" at what is going on here: yes mapcar
can operate on strings and return strings in TXR Lisp. (repeat key)
produces an infinite lazy list; but that's okay because mapcar
stops after the shortest input runs out of items.
Run:
$ txr vigenere.txr 'vigenere cipher' 'Beware the Jabberwock... The jaws that... the claws that catch!' text: BEWARETHEJABBERWOCKTHEJAWSTHATTHECLAWSTHATCATCH key: VIGENERECIPHER enc: WMCEEIKLGRPIFVMEUGXXYILILZXYVBZLRGCEYAIOEKXIZGU dec: GWQWEACDCBLUXNWOIYXPQAHSHLPQFLNDRYUWUKEAWCHSNYU check: BEWARETHEJABBERWOCKTHEJAWSTHATTHECLAWSTHATCATCH
TypeScript
class Vigenere {
key: string
/** Create new cipher based on key */
constructor(key: string) {
this.key = Vigenere.formatText(key)
}
/** Enrypt a given text using key */
encrypt(plainText: string): string {
return Array.prototype.map.call(Vigenere.formatText(plainText), (letter: string, index: number): string => {
return String.fromCharCode((letter.charCodeAt(0) + this.key.charCodeAt(index % this.key.length) - 130) % 26 + 65)
}).join('')
}
/** Decrypt ciphertext based on key */
decrypt(cipherText: string): string {
return Array.prototype.map.call(Vigenere.formatText(cipherText), (letter: string, index: number): string => {
return String.fromCharCode((letter.charCodeAt(0) - this.key.charCodeAt(index % this.key.length) + 26) % 26 + 65)
}).join('')
}
/** Converts to uppercase and removes non characters */
private static formatText(text: string): string {
return text.toUpperCase().replace(/[^A-Z]/g, "")
}
}
/** Example usage */
(() => {
let original: string = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."
console.log(`Original: ${original}`)
let vig: Vigenere = new Vigenere("vigenere")
let encoded: string = vig.encrypt(original)
console.log(`After encryption: ${encoded}`)
let back: string = vig.decrypt(encoded)
console.log(`After decryption: ${back}`)
})()
VBA
Option Explicit
Sub test()
Dim Encryp As String
Encryp = Vigenere("Beware the Jabberwock, my son! The jaws that bite, the claws that catch!", "vigenerecipher", True)
Debug.Print "Encrypt:= """ & Encryp & """"
Debug.Print "Decrypt:= """ & Vigenere(Encryp, "vigenerecipher", False) & """"
End Sub
Private Function Vigenere(sWord As String, sKey As String, Enc As Boolean) As String
Dim bw() As Byte, bk() As Byte, i As Long, c As Long
Const sW As String = "ÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ"
Const sWo As String = "AAAAACEEEEIIIINOOOOOUUUUY"
Const A As Long = 65
Const N As Long = 26
c = Len(sKey)
i = Len(sWord)
sKey = Left(IIf(c < i, StrRept(sKey, (i / c) + 1), sKey), i)
sKey = StrConv(sKey, vbUpperCase) 'Upper case
sWord = StrConv(sWord, vbUpperCase)
sKey = StrReplace(sKey, sW, sWo) 'Replace accented characters
sWord = StrReplace(sWord, sW, sWo)
sKey = RemoveChars(sKey) 'Remove characters (numerics, spaces, comas, ...)
sWord = RemoveChars(sWord)
bk = CharToAscii(sKey) 'To work with Bytes instead of String
bw = CharToAscii(sWord)
For i = LBound(bw) To UBound(bw)
Vigenere = Vigenere & Chr((IIf(Enc, ((bw(i) - A) + (bk(i) - A)), ((bw(i) - A) - (bk(i) - A)) + N) Mod N) + A)
Next i
End Function
Private Function StrRept(s As String, N As Long) As String
Dim j As Long, c As String
For j = 1 To N
c = c & s
Next
StrRept = c
End Function
Private Function StrReplace(s As String, What As String, By As String) As String
Dim t() As String, u() As String, i As Long
t = SplitString(What)
u = SplitString(By)
StrReplace = s
For i = LBound(t) To UBound(t)
StrReplace = Replace(StrReplace, t(i), u(i))
Next i
End Function
Private Function SplitString(s As String) As String()
SplitString = Split(StrConv(s, vbUnicode), Chr(0))
End Function
Private Function RemoveChars(str As String) As String
Dim b() As Byte, i As Long
b = CharToAscii(str)
For i = LBound(b) To UBound(b)
If b(i) >= 65 And b(i) <= 90 Then RemoveChars = RemoveChars & Chr(b(i))
Next i
End Function
Private Function CharToAscii(s As String) As Byte()
CharToAscii = StrConv(s, vbFromUnicode)
End Function
- Output:
Encrypt:= "WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY" Decrypt:= "BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH"
VBScript
Function Encrypt(text,key)
text = OnlyCaps(text)
key = OnlyCaps(key)
j = 1
For i = 1 To Len(text)
ms = Mid(text,i,1)
m = Asc(ms) - Asc("A")
ks = Mid(key,j,1)
k = Asc(ks) - Asc("A")
j = (j Mod Len(key)) + 1
c = (m + k) Mod 26
c = Chr(Asc("A")+c)
Encrypt = Encrypt & c
Next
End Function
Function Decrypt(text,key)
key = OnlyCaps(key)
j = 1
For i = 1 To Len(text)
ms = Mid(text,i,1)
m = Asc(ms) - Asc("A")
ks = Mid(key,j,1)
k = Asc(ks) - Asc("A")
j = (j Mod Len(key)) + 1
c = (m - k + 26) Mod 26
c = Chr(Asc("A")+c)
Decrypt = Decrypt & c
Next
End Function
Function OnlyCaps(s)
For i = 1 To Len(s)
char = UCase(Mid(s,i,1))
If Asc(char) >= 65 And Asc(char) <= 90 Then
OnlyCaps = OnlyCaps & char
End If
Next
End Function
'testing the functions
orig_text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
orig_key = "vigenerecipher"
WScript.StdOut.WriteLine "Original: " & orig_text
WScript.StdOut.WriteLine "Key: " & orig_key
WScript.StdOut.WriteLine "Encrypted: " & Encrypt(orig_text,orig_key)
WScript.StdOut.WriteLine "Decrypted: " & Decrypt(Encrypt(orig_text,orig_key),orig_key)
- Output:
Original: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Key: vigenerecipher Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
An alternate implementation using RegExp to filter the input
'vigenere cypher
option explicit
const asca =65 'ascii(a)
function filter(s)
with new regexp
.pattern="[^A-Z]"
.global=1
filter=.replace(ucase(s),"")
end with
end function
function vigenere (s,k,sign)
dim s1,i,a,b
for i=0 to len(s)-1
a=asc(mid(s,i+1,1))-asca
b=sign * (asc(mid(k,(i mod len(k))+1,1))-asca)
s1=s1 & chr(((a+b+26) mod 26) +asca)
next
vigenere=s1
end function
function encrypt(s,k): encrypt=vigenere(s,k,1) :end function
function decrypt(s,k): decrypt=vigenere(s,k,-1) :end function
'test--------------------------
dim plaintext,filtered,key,encoded
key="VIGENERECYPHER"
plaintext = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
filtered= filter(plaintext)
wscript.echo filtered
encoded=encrypt(filtered,key)
wscript.echo encoded
wscript.echo decrypt(encoded,key)
Vedit macro language
Encrypts and then decrypts one line of text on current edit buffer, starting from cursor location. The user enters the keyword (upper or lower case).
Get_Input(10, "Key: ", STATLINE+NOCR) // @10 = key
Reg_Copy_Block(11, Cur_Pos, EOL_Pos) // @11 = copy of original text
EOL Ins_Newline
Ins_Text("Key = ") Reg_Ins(10) Ins_Newline
// Prepare the key into numeric registers #130..:
Buf_Switch(Buf_Free)
Reg_Ins(10)
Case_Upper_Block(0, Cur_Pos)
BOF
#2 = Reg_Size(10) // #2 = key length
for (#3=130; #3 < 130+#2; #3++) {
#@3 = Cur_Char
Char(1)
}
Buf_Quit(OK)
Ins_Text("Encrypted: ")
#4 = Cur_Pos
Reg_Ins(11) // copy of original text
Replace_Block("|!|A", "", #4, EOL_Pos, BEGIN+ALL+NOERR) // remove non-alpha chars
Case_Upper_Block(#4, EOL_Pos) // convert to upper case
Goto_Pos(#4)
#1 = 1; Call("ENCRYPT_DECRYPT") // Encrypt the line
Reg_Copy_Block(11, #4, Cur_Pos) // Copy encrypted text text to next line
Ins_Newline
Ins_Text("Decrypted: ")
Reg_Ins(11, BEGIN)
#1 = -1; Call("ENCRYPT_DECRYPT") // Decrypt the line
Return
// Encrypt or decrypt text on current line in-place, starting from cursor position.
// in: #1 = direction (1=encrypt, -1=decrypt)
// #2 = key length, #130...#189 = the key
//
:ENCRYPT_DECRYPT:
Num_Push(6,9)
#6 = 0
While (!At_EOL) {
#7 = #6+130 // pointer to key array
#8 = #@7 // get key character
#9 = (Cur_Char + #8*#1 + 26) % 26 + 'A' // decrypt/encrypt
Ins_Char(#9, OVERWRITE) // write the converted char
#6 = (#6+1) % #2
}
Num_Pop(6,9)
Return
- Output:
Beware the Jabberwock, my son! The jaws that bite, the claws that catch! Key = vigenerecipher Encrypted: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Decrypted: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
V (Vlang)
const
(
key = "VIGENERECIPHER"
text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
)
fn main() {
encoded := vigenere(text, key, true)
println(encoded)
decoded := vigenere(encoded, key, false)
println(decoded)
}
fn vigenere(str string, key string, encrypt bool) string {
mut txt :=''
mut chr_arr := []u8{}
mut kidx, mut cidx := 0, 0
if encrypt == true {txt = str.to_upper()}
else {txt = str}
for chr in txt {
if (chr > 64 && chr < 91) == false {continue}
if encrypt == true {cidx = (chr + key[kidx] - 130) % 26}
else {cidx = (chr - key[kidx] + 26) % 26}
chr_arr << u8(cidx + 65)
kidx = (kidx + 1) % key.len
}
return chr_arr.bytestr()
}
- Output:
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
Wren
import "./str" for Char, Str
var vigenere = Fn.new { |text, key, encrypt|
var t = encrypt ? Str.upper(text) : text
var sb = ""
var ki = 0
for (c in t) {
if (Char.isAsciiUpper(c)) {
var ci = encrypt ? (c.bytes[0] + key[ki].bytes[0] - 130) % 26 :
(c.bytes[0] - key[ki].bytes[0] + 26) % 26
sb = sb + Char.fromCode(ci + 65)
ki = (ki + 1) % key.count
}
}
return sb
}
var key = "VIGENERECIPHER"
var text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
var encoded = vigenere.call(text, key, true)
System.print(encoded)
var decoded = vigenere.call(encoded, key, false)
System.print(decoded)
- Output:
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
XPL0
The KEYWORD must be UPPERCASE. Precede it with a minus sign to decrypt a file. Usage: vigenere KEYWORD <infile.txt >outfile.xxx
code ChIn=7, ChOut=8;
int Neg, C, Len, I, Key;
char KeyWord(80);
[Neg:= false; \skip to KEYWORD
repeat C:= ChIn(8); if C=^- then Neg:= true; until C>=^A & C<=^Z;
Len:= 0; \read in KEYWORD
repeat KeyWord(Len):= C-^A; Len:= Len+1; C:= ChIn(8); until C<^A ! C>^Z;
I:= 0; \initialize cycling index
repeat C:= ChIn(1);
if C>=^a & C<=^z then C:= C-$20; \capitalize
if C>=^A & C<=^Z then \discard non-alphas
[Key:= KeyWord(I); I:= I+1; if I>=Len then I:= 0;
if Neg then Key:= -Key; \decrypting?
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
ChOut(0, $1A); \encrypted file must end with EOF otherwise the decode will hang
]
- Output:
KEYWORD = ACE infile = Pack my box with five dozen liquor jugs. outfile = PCGKOCBQBWKXHHMVGHOBINNMQWSRLYGU KEYWORD = -ACE outfile = PACKMYBOXWITHFIVEDOZENLIQUORJUGS
Zig
const std = @import("std");
const Allocator = std.mem.Allocator;
const Vigenere = enum {
encode,
decode,
};
pub fn main() anyerror!void {
// ------------------------------------------ allocator
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
const ok = gpa.deinit();
std.debug.assert(ok == .ok);
}
const allocator = gpa.allocator();
// --------------------------------------------- stdout
const stdout = std.io.getStdOut().writer();
// ----------------------------------------------------
const key = "VIGENERECIPHER";
const text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!";
const encoded = try vigenere(allocator, text, key, .encode);
defer allocator.free(encoded);
try stdout.print("{s}\n", .{encoded});
const decoded = try vigenere(allocator, encoded, key, .decode);
defer allocator.free(decoded);
try stdout.print("{s}\n", .{decoded});
}
/// Caller owns the returned slice memory.
fn vigenere(allocator: Allocator, text: []const u8, key: []const u8, mode: Vigenere) Allocator.Error![]u8 {
var dynamic_string = std.ArrayList(u8).init(allocator);
var key_index: usize = 0;
for (text) |letter| {
const c = if (std.ascii.isLower(letter)) std.ascii.toUpper(letter) else letter;
if (std.ascii.isUpper(c)) {
const k = key[key_index];
const n = switch (mode) {
.encode => ((c - 'A') + (k - 'A')),
.decode => 26 + c - k,
};
try dynamic_string.append(n % 26 + 'A'); // A-Z
key_index += 1;
key_index %= key.len;
}
}
return dynamic_string.toOwnedSlice();
}
- Output:
WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
zkl
fcn encipher(src,key,is_encode){
upperCase:=["A".."Z"].pump(String);
src=src.toUpper().inCommon(upperCase); // only uppercase
key=key.toUpper().inCommon(upperCase).pump(List,"toAsc");
const A="A".toAsc();
klen:=Walker.cycle(key.len()); // 0,1,2,3,..,keyLen-1,0,1,2,3, ...
src.pump(String,'wrap(c){ i:=klen.next(); c=c.toAsc();
(A + ( if(is_encode) c - A + key[i] - A;
else c - key[i] + 26 ) % 26).toChar()
});
}
str := "Beware the Jabberwock, my son! The jaws that bite, "
"the claws that catch!";
key := "Vigenere Cipher";
println("Text: ", str);
println("key: ", key);
cod := encipher(str, key, True); println("Code: ", cod);
dec := encipher(cod, key, False); println("Back: ", dec);
- Output:
Text: Beware the Jabberwock, my son! The jaws that bite, the claws that catch! key: Vigenere Cipher Code: WMCEEIKLGRPIFVMEUGXQPWQVIOIAVEYXUEKFKBTALVXTGAFXYEVKPAGY Back: BEWARETHEJABBERWOCKMYSONTHEJAWSTHATBITETHECLAWSTHATCATCH
- Programming Tasks
- Encryption
- String manipulation
- GUISS/Omit
- Openscad/Omit
- 11l
- Action!
- Ada
- ALGOL 68
- Applesoft BASIC
- Arturo
- AutoHotkey
- BASIC256
- BBC BASIC
- Befunge
- C
- C sharp
- C++
- Ceylon
- Clojure
- CoffeeScript
- Common Lisp
- D
- Delphi
- SysUtils,StdCtrls
- EasyLang
- Elena
- Elixir
- Erlang
- F Sharp
- Factor
- Fortran
- FreeBASIC
- Go
- Haskell
- Icon
- Unicon
- Icon Programming Library
- J
- Java
- JavaScript
- Jq
- Jsish
- Julia
- Kotlin
- Lambdatalk
- Liberty BASIC
- Lua
- Mathematica
- Wolfram Language
- NetRexx
- Nim
- Objeck
- OCaml
- OoRexx
- Pascal
- Perl
- Phix
- PHP
- PicoLisp
- PL/I
- PowerShell
- PureBasic
- Python
- Quackery
- R
- Racket
- Raku
- Red
- REXX
- Ring
- RPL
- Ruby
- Rust
- Scala
- Seed7
- Sidef
- Smalltalk
- Swift
- Tcl
- TXR
- TypeScript
- VBA
- VBScript
- Vedit macro language
- V (Vlang)
- Wren
- Wren-str
- XPL0
- Zig
- Zkl