> | # a little bit of cryptography: |
> | with(StringTools): |
> | Map( Capitalize, "This is a test." );
|
> | Map( LowerCase, %);
|
> | convert("Test string", 'bytes');
|
> | convert([65,66,67], 'bytes');
|
> | convert("abcdefghijklmnopqrstuvwxyz", 'bytes');
|
> | convert("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 'bytes');
|
> | # irem(a, b) gives the remainder r of a upon division by b,
# i.e. the r in a = q * b + r with 0 <= r < b. # For example, |
> | irem(17,5);
|
> | # but |
> | irem(-1,5);
|
> | # the Caesar cipher is the following:
# it takes the plaintext and shifts the letters # alphabetically by some fixed amount # For instance, a shift by 3 amounts to # a -> d # b -> e # c -> f # ... # w -> z # x -> a # y -> b # z -> d # # So, abc becomes def, for instance. # to decipher, oneft back the other direction by the same amount. |
> | # now we implement the Caesar cipher,
# which is shifting the letters of the alphabet by some fixed amount |
> | caesar := proc(s::string, shift::integer)
local S, l, i, c; S := convert(s,'bytes'); l := nops(S); for i to l do c := S[i]; if c >= 97 and c <= 122 then c := c - 97 + shift; c := irem(c, 26); if c < 0 then c := c + 26; end; S[i] := 97 + c; end; end; return convert(S,'bytes'); end; |
> | # encryption: |
> | caesar("abcdefghijklmnopqrstuvwxyz", 3);
|
> | # decryption using the negative shift |
> | caesar(%, -3);
|
> | caesar("abcdefghijklmnopqrstuvwxyz", 26);
|
> |
> |
> |
> | vigenere_cipher := proc(s::string, k::string)
local S, l, K, kl, i, j, c, d; S := convert(s,'bytes'); l := nops(S); K := convert(k,'bytes'); kl := nops(K); for i to l do j := irem(i, kl) + 1; c := S[i]; d := K[j]; if c >= 97 and c <= 122 then c := c - 97; c := c + d; c := irem(c, 26); if c < 0 then c := c + 26; end; S[i] := 97 + c; end; end; return convert(S,'bytes'); end: |
> | p := "Shake and quiver, little tree, Throw gold and silver down to me"; |
> | c := vigenere_cipher(p, "verysecret"); |
> | vigenere_decipher := proc(s::string, k::string)
local S, l, K, kl, i, j, c, d; S := convert(s,'bytes'); l := nops(S); K := convert(k,'bytes'); kl := nops(K); for i to l do j := irem(i, kl) + 1; c := S[i]; d := K[j]; if c >= 97 and c <= 122 then c := c - 97; c := c - d; while c < 0 do c := c + 26; end; c := irem(c, 26); S[i] := 97 + c; end; end; return convert(S,'bytes'); end: |
> | vigenere_decipher(c, "verysecret"); |
> | p := "I have seen too much not to know that the impression of a woman may be more valuable than the conclusion of an analytical reasoner."; |
> | vigenere_cipher(p, "arthurdoyle");
|
Error, (in vigenere_cipher) assigning to a long list, please use Arrays
> | S := convert(p,'bytes'); |
> | S[1] := 100; |
Error, assigning to a long list, please use Arrays
> | T := Array(S); |
> | T[1]; |
> | vigenere_cipher := proc(s::string, k::string)
local S, T, L, l, K, kl, i, j, c, d; S := convert(s,'bytes'); T := Array(S); l := nops(S); K := convert(k,'bytes'); kl := nops(K); for i to l do j := irem(i, kl) + 1; c := T[i]; d := K[j]; if c >= 97 and c <= 122 then c := c - 97; c := c + d; c := irem(c, 26); if c < 0 then c := c + 26; end; T[i] := 97 + c; end; end; L := []; for i to l do L := [op(L),T[i]]; end; return convert(L,'bytes'); end: |
> |
> | vigenere_cipher(p, "arthurdoyle"); |
> | # HOMEWORK
# |
> | # |
> | # 1)
# The Nero cipher exchanges a and z, b and y, c and x etc. # Write a procedure to encrypt using the Nero cipher. # Take your favourite text and encrypt it with # 7 Caeser, one Nero and 12 more Caesar ciphers. # What do you get? # How do you decipher it? # Can you decipher it using only one n-fold Caesar and one Nero step? |
> | # 2) re-write thefunction vigenere_decipher() to use an Array
# (to make it work for long strings.) # Then decipher the following piece (the key is jane) # "Wnv, sv wkxt, vqn jwlz mgut, Mou. Lqgm utep mnxv Nbvakohbkif op mghgg ya g ahaki sxp uc egoix cqkzrpx cths vak phxqj uc Etdntta" # # 3) re-write the functions vigenere_cipher and vigenere_cipher # to also encrypt capital letters. |
> | # Use this function the encrypt the text of 2) with the key jane.
|
> |
> |
> |