Down below I am sharing with you the question and what I wrote as a solution so far. It includes the commands, functions, outputs, and errors. I am struggling with fixing my errors as I have tried numerous ways to correct them. However, I either get new errors or previous errors. Was wondering if someone can look at it and provide me advice, and a possible solution to the problem.
In this question, you are given a cypher that was obtained using a Vigenere cypher, care of question 2, and are asked to decipher it. You will use the approach outlined in Section 5.2 of the text. There are two steps: 1) Determine the key length by finding the shift which produces the maximum number of coincidences, 2) use frequency analysis on the subsequences obtained by selecting symbols from the cypher at multiples of the key length to determine the key. The details of these steps will be outlined below. You will be asked to write several maple procedures that assist in this process.
restart;
with(StringTools):
with(LinearAlgebra):
cstr := "eqjyvxvgiuphmrrrgzhvwrrukmrtijfbtodidtsjsgofwmfalkeveolqlmhkfhrerhwuidejonvjuumklhliiwwnajxbonjthitzsqufklhihrvditvvvzhvwhihrvditvvvgsrrbunvqlmhkvhgdzpbmuvwvloiqdiiglhxtyewosksvgyklhecfrykyrqhgnzrjhukxkknwvrswyewosbrrcnfjnodumfuuchqutjysvojikomtesgbcirlcfrvzrlgwonxeqeowxkkmfvhgbjxuasvguepksjxaglvomrhhapdcponuewuntiwnakxkosnevufrwlspcivvetmhyslgknoniykrrwzuuchdvpveuzoklhirlhhonkioretxrltyivgicsugbjsoatvpbonjsoabcizotysxztyinky";
cstr := "eqjyvxvgiuphmrrrgzhvwrrukmrtijfbtodidtsjsgofwmfalkeveol\
qlmhkfhrerhwuidejonvjuumklhliiwwnajxbonjthitzsqufklhihrvditvvv\
zhvwhihrvditvvvgsrrbunvqlmhkvhgdzpbmuvwvloiqdiiglhxtyewosksvgy\
klhecfrykyrqhgnzrjhukxkknwvrswyewosbrrcnfjnodumfuuchqutjysvoji\
komtesgbcirlcfrvzrlgwonxeqeowxkkmfvhgbjxuasvguepksjxaglvomrhha\
pdcponuewuntiwnakxkosnevufrwlspcivvetmhyslgknoniykrrwzuuchdvpv\
euzoklhirlhhonkioretxrltyivgicsugbjsoatvpbonjsoabcizotysxztyin\
ky"
n := Length(cstr);
n := 429
a) Determine the key length. Write a Maple function to determine the key length given the ciphertext obtained from a Vigenere cipher with unknown key using a specified alphabet. Use one of the methods outlined in section 5.2 of the text: the Kasiski test (using trigrams) or the index of coincidence test. For the Kasiski test, the key length is suggested by the greatest common divisor of the distances between most of the repeated trigrams. For the index of coincidence test, construct the subsequences described in part (b) for various values of
k;
. The
k;
value that yields the highest average index of coincidence of these subsequences most likely is the key length.
KasiskiTest := proc(str)
local i, j, n, trigrams, distances, gcds, freqs;
n := StringTools:-Length(str);
trigrams := table();
distances := table();
gcds := table();
freqs := table();
for i from 1 to n-2 do
trigrams[str[i..i+2]] := [op(trigrams[str[i..i+2]]),i];
end do;
for j in trigrams do
if nops(trigrams[j]) > 1 then
distances[j] := map(diff,trigrams[j]);
gcds[j] := igcd(op(distances[j]));
freqs[gcds[j]] := freqs[gcds[j]] + 1;
end if;
end do;
return maxloc(freqs);
end;
IndexCoincidenceTest := proc(str)
local i, k, n, m, L, C, Convert, IC, avgIC;
Convert := table(); n := StringTools:-Length(str);
for i from 1 to n do
Convert[str[i]] := i-1;
end do;
L := Letter2Number(str,Convert);
IC := [];
avgIC := [];
for k from 1 to n/2 do
C := [];
for i from 1 to k do
C[i] := seq(L[i+j*k],j=0..floor((n-i)/k));
end do;
IC[k] := map(DotProduct,C,C)/nops(C)^2;
avgIC[k] := add(IC[k])/k;
end do;
return maxloc(avgIC);
end;
KasiskiTest(cstr);
maxloc(freqs)
IndexCoincidenceTest(cstr);
Error, (in IndexCoincidenceTest) expression sequences cannot be assigned to lists
b) Construct subsequences of the cypher by selecting characters at multiples of the key length. I.E. If k is the key length, then construct subsequences: c1 = cstr[1],cstr[1+k],...,cstr[1+n/k],...,ck = cstr[k],cstr[2*k],...,cstr[floor(n/k)*k].
Maple hint: use seq and cat to form these strings.
cstr := "eqjyvxvgiuphmrrrgzhvwrrukmrtijfbtodidtsjsgofwmfalkeveolqlmhkfhrerhwuidejonvjuumklhliiwwnajxbonjthitzsqufklhihrvditvvvzhvwhihrvditvvvgsrrbunvqlmhkvhgdzpbmuvwvloiqdiiglhxtyewosksvgyklhecfrykyrqhgnzrjhukxkknwvrswyewosbrrcnfjnodumfuuchqutjysvojikomtesgbcirlcfrvzrlgwonxeqeowxkkmfvhgbjxuasvguepksjxaglvomrhhapdcponuewuntiwnakxkosnevufrwlspcivvetmhyslgknoniykrrwzuuchdvpveuzoklhirlhhonkioretxrltyivgicsugbjsoatvpbonjsoabcizotysxztyinky";
cstr := "eqjyvxvgiuphmrrrgzhvwrrukmrtijfbtodidtsjsgofwmfalkeveol\
qlmhkfhrerhwuidejonvjuumklhliiwwnajxbonjthitzsqufklhihrvditvvv\
zhvwhihrvditvvvgsrrbunvqlmhkvhgdzpbmuvwvloiqdiiglhxtyewosksvgy\
klhecfrykyrqhgnzrjhukxkknwvrswyewosbrrcnfjnodumfuuchqutjysvoji\
komtesgbcirlcfrvzrlgwonxeqeowxkkmfvhgbjxuasvguepksjxaglvomrhha\
pdcponuewuntiwnakxkosnevufrwlspcivvetmhyslgknoniykrrwzuuchdvpv\
euzoklhirlhhonkioretxrltyivgicsugbjsoatvpbonjsoabcizotysxztyin\
ky"
Subsequences := proc(str,k)
local i, n, C, S;
n := StringTools:-Length(str);
C := [];
S := [];
for i from 1 to k do
C[i] := seq(str[i+j*k],j=0..floor((n-i)/k));
S[i] := cat(op(C[i]));
end do;
return S;
end;
Warning, (in Subsequences) `j` is implicitly declared local
Subsequences := proc (str, k) local i, n, C, S, j; n :=
StringTools:-Length(str); C := []; S := []; for i to k do
C[i] := seq(str[i+j*k], j = 0 .. floor((n-i)/k)); S[i] :=
cat(op(C[i])) end do; return S end proc
Subsequences(cstr,4);
Error, (in Subsequences) expression sequences cannot be assigned to lists
c) Calculate the character frequencies in the substrings formed from (b). You should construct a list F=[f1/n,...,ft/n], where fi is the number of occurrences of symbol i in the string and n is the number of symbols in the string, and t is the number of symbols in the alphabet. Don't forget that you can use evalf() to get a floating point approximation to the fractions fi/n, and you can use CountCharacterOccurrences() from the StringTools package to obtain the number of occurrences of the ith symbol. For the alphabet use a,...,z. See question 1.
alphabet := Iota("a".."z");
alphabet := "abcdefghijklmnopqrstuvwxyz"
CharacterFrequencies := proc(str,alphabet)
local i, n, t, F, C;
n := StringTools:-Length(str);
t := StringTools:-Length(alphabet);
F := [];
C := StringTools:-CountCharacterOccurrences(str);
for i from 1 to t do
F[i] := evalf(C[alphabet[i]]/n);
end do;
return F;
end;
Error, attempting to assign to `StringTools:-CharacterFrequencies` which is protected
alphabet := "abcdefghijklmnopqrstuvwxyz";
S := Subsequences(cstr,4);
CharacterFrequencies(S[1],alphabet);
alphabet := "abcdefghijklmnopqrstuvwxyz"
Error, (in Subsequences) expression sequences cannot be assigned to lists
Error, (in StringTools:-CharacterFrequencies) first argument must be a string
d) Determine the Ceasar shifts for the 5 subsequences from (b) and hence determine the key. This is done by comparing the frequencies computed in (c) with the standard English letter probabilities given in the list FE.
You are to write a function FindShift(F1,F2) which takes as input F1 = the standard frequencies and F2 = the shifted frequencies. The function FindShift(F1,F2) find the shift
"s"
which minimizes the error between the two lists of frequencies. I.E. For each possible shift
"s=0,1,...,25 = nops(F1), "
compute the sum of the squares of the difference F1[i]-F2[i+s mod 26]. Find the value of
"s"
that minimizes this sum. This will be the most likely shift.
Note that in the above sum, you will need to correct the indexing due to the fact that Maple indexes lists and arrays starting at 1 rather than 0.
Use the function FindShift to find the key used to create the cypher cstr.
FE := [0.8167000000e-1, 0.1492000000e-1, 0.2782000000e-1, 0.4253000000e-1, .1270200000, 0.2228000000e-1, 0.2015000000e-1, 0.6094000000e-1, 0.6966000000e-1, 0.1530000000e-2, 0.7720000000e-2, 0.4025000000e-1, 0.2406000000e-1, 0.6749000000e-1, 0.7507000000e-1, 0.1929000000e-1, 0.9500000000e-3, 0.5987000000e-1, 0.6327000000e-1, 0.9056000000e-1, 0.2758000000e-1, 0.9780000000e-2, 0.2360000000e-1, 0.1500000000e-2, 0.1974000000e-1, 0.7400000000e-3];
[0.08167000000, 0.01492000000, 0.02782000000, 0.04253000000,
0.1270200000, 0.02228000000, 0.02015000000, 0.06094000000,
0.06966000000, 0.001530000000, 0.007720000000, 0.04025000000,
0.02406000000, 0.06749000000, 0.07507000000, 0.01929000000,
0.0009500000000, 0.05987000000, 0.06327000000, 0.09056000000,
0.02758000000, 0.009780000000, 0.02360000000, 0.001500000000,
0.01974000000, 0.0007400000000]
FindShift := proc(F1,F2)
local i, s, n, t, S, M;
n := nops(F1);
t := nops(F2);
S := [];
for s from 0 to n-1 do
S[s+1] := add((F1[i]-F2[(i+s) mod t + 1])^2,i=1..n);
end do;
M := minloc(S);
return M[2]-1;
end;
FindShift := proc (F1, F2) local i, s, n, t, S, M; n :=
nops(F1); t := nops(F2); S := []; for s from 0 to n-1 do
S[s+1] := add((F1[i]-F2[(`mod`(i+s, t))+1])^2, i = 1 .. n)
end do; M := minloc(S); return M[2]-1 end proc
with(StringTools);
alphabet := "abcdefghijklmnopqrstuvwxyz";
cstr := "eqjyvxvgiuphmrrrgzhvwrrukmrtijfbtodidtsjsgofwmfalkeveolqlmhkfhrerhwuidejonvjuumklhliiwwnajxbonjthitzsqufklhihrvditvvvzhvwhihrvditvvvgsrrbunvqlmhkvhgdzpbmuvwvloiqdiiglhxtyewosksvgyklhecfrykyrqhgnzrjhukxkknwvrswyewosbrrcnfjnodumfuuchqutjysvojikomtesgbcirlcfrvzrlgwonxeqeowxkkmfvhgbjxuasvguepksjxaglvomrhhapdcponuewuntiwnakxkosnevufrwlspcivvetmhyslgknoniykrrwzuuchdvpveuzoklhirlhhonkioretxrltyivgicsugbjsoatvpbonjsoabcizotysxztyinky";
FE := [0.8167000000e-1, 0.1492000000e-1, 0.2782000000e-1, 0.4253000000e-1, .1270200000, 0.2228000000e-1, 0.2015000000e-1, 0.6094000000e-1, 0.6966000000e-1, 0.1530000000e-2, 0.7720000000e-2, 0.4025000000e-1, 0.2406000000e-1, 0.6749000000e-1, 0.7507000000e-1, 0.1929000000e-1, 0.9500000000e-3, 0.5987000000e-1, 0.6327000000e-1, 0.9056000000e-1, 0.2758000000e-1, 0.9780000000e-2, 0.2360000000e-1, 0.1500000000e-2, 0.1974000000e-1, 0.7400000000e-3];
Subsequences := proc(str,k)
local i, n, C, S;
n := StringTools:-Length(str);
C := [];
S := [];
for i from 1 to k do
C[i] := seq(str[i+j*k],j=0..floor((n-i)/k));
S[i] := cat(op(C[i]));
end do;
return S;
end;
CharacterFrequencies := proc(str,alphabet)
local i, n, t, F, C;
n := StringTools:-Length(str);
t := StringTools:-Length(alphabet);
F := [];
C := StringTools:-CountCharacterOccurrences(str);
for i from 1 to t do
F[i] := evalf(C[alphabet[i]]/n);
end do;
return F;
end;
FindShift := proc(F1,F2)
local i, s, n, t, S, M;
n := nops(F1);
t := nops(F2);
S := [];
for s from 0 to n-1 do
S[s+1] := add((F1[i]-F2[(i+s) mod t + 1])^2,i=1..n);
end do;
M := minloc(S);
return M[2]-1;
end;
S := Subsequences(cstr,4);
F := map(CharacterFrequencies,S,alphabet);
Shifts := map(FindShift,FE,F);
KeyLetters := map(Number2Letter,Shifts,alphabet);
Key := cat(op(KeyLetters));
[Anagrams, AndMap, ApproximateSearch, ApproximateSearchAll,
ArithmeticMean, Border, BorderArray, BorderLength, CamelCase,
Capitalize, CaseJoin, CaseSplit, Center, Centre, Char,
CharacterFrequencies, CharacterMap, Chomp, Chop, CommonPrefix,
CommonSuffix, Compare, CompareCI, Compress,
CountCharacterOccurrences, Decode, DecodeEntities, Delete,
DeleteSpace, DifferencePositions, Drop, EditDistance, Encode,
EncodeEntities, Entropy, Escape, Exchange,
ExpandCharacterClass, ExpandTabs, Explode, Fence, Fibonacci,
Fill, FirstFromLeft, FirstFromRight, FormatMessage, FormatTime,
FromByteArray, Generate, GenerateIdentifier, Group,
HammingDistance, HammingSearch, HammingSearchAll, Has,
HasASCII, HasAlpha, HasAlphaNumeric, HasBinaryDigit,
HasControlCharacter, HasDigit, HasGraphic, HasHexDigit,
HasIdentifier, HasIdentifier1, HasLower, HasOctalDigit,
HasPrintable, HasPunctuation, HasSpace, HasUpper, HasVowel,
Hash, Implode, Indent, IndexOfCoincidence, Insert, Iota,
IsASCII, IsAlpha, IsAlphaNumeric, IsAnagram, IsBalanced,
IsBinaryDigit, IsConjugate, IsControlCharacter, IsDerangement,
IsDigit, IsEodermdrome, IsGraphic, IsHexDigit, IsIdentifier,
IsIdentifier1, IsLower, IsMonotonic, IsOctalDigit,
IsPalindrome, IsPeriod, IsPermutation, IsPrefix, IsPrimitive,
IsPrintable, IsPunctuation, IsSorted, IsSpace, IsSubSequence,
IsSuffix, IsUpper, IsVowel, Join, Kasiski, LeftFold,
LeftRecursivePathOrder, Length, LengthSplit, Levenshtein,
LexOrder, LongestCommonSubSequence, LongestCommonSubString,
LowerCase, LyndonFactors, Map, MatchFence, MaxChar,
MaximalPalindromicSubstring, Metaphone, MinChar,
MinimumConjugate, MonotonicFactors, NGrams, NthWord, OrMap,
Ord, OtherCase, Overlap, PadLeft, PadRight, ParseTime,
PatternCanonicalForm, PatternDictionary, PatternEquivalent,
Period, Permute, PrefixDistance, PrimitiveRoot, Random,
Randomize, Readability, RegMatch, RegSplit, RegSub, RegSubs,
Remove, Repeat, Repeats, RevLexOrder, Reverse, RightFold,
RightRecursivePathOrder, Rotate, Search, SearchAll, Select,
SelectRemove, Sentences, Shift, ShortLexOrder,
ShortRevLexOrder, SimilarityCoefficient, Snarf, Sort,
SortPermutation, Soundex, Split, Squeeze, Stem, StringBuffer,
StringSplit, SubString, Subs, Substitute, SubstituteAll,
SuffixDistance, Support, SyllableLength, Tabulate, Take,
ThueMorse, ToByteArray, Trim, TrimLeft, TrimRight, Uncompress,
Unique, UpperCase, Visible, WildcardMatch, WordContaining,
WordCount, WordEnd, WordStart, Words, WrapText]
alphabet := "abcdefghijklmnopqrstuvwxyz"
cstr := "eqjyvxvgiuphmrrrgzhvwrrukmrtijfbtodidtsjsgofwmfalkeveol\
qlmhkfhrerhwuidejonvjuumklhliiwwnajxbonjthitzsqufklhihrvditvvv\
zhvwhihrvditvvvgsrrbunvqlmhkvhgdzpbmuvwvloiqdiiglhxtyewosksvgy\
klhecfrykyrqhgnzrjhukxkknwvrswyewosbrrcnfjnodumfuuchqutjysvoji\
komtesgbcirlcfrvzrlgwonxeqeowxkkmfvhgbjxuasvguepksjxaglvomrhha\
pdcponuewuntiwnakxkosnevufrwlspcivvetmhyslgknoniykrrwzuuchdvpv\
euzoklhirlhhonkioretxrltyivgicsugbjsoatvpbonjsoabcizotysxztyin\
ky"
FE := [0.08167000000, 0.01492000000, 0.02782000000,
0.04253000000, 0.1270200000, 0.02228000000, 0.02015000000,
0.06094000000, 0.06966000000, 0.001530000000, 0.007720000000,
0.04025000000, 0.02406000000, 0.06749000000, 0.07507000000,
0.01929000000, 0.0009500000000, 0.05987000000, 0.06327000000,
0.09056000000, 0.02758000000, 0.009780000000, 0.02360000000,
0.001500000000, 0.01974000000, 0.0007400000000]
Warning, (in Subsequences) `j` is implicitly declared local
Subsequences := proc (str, k) local i, n, C, S, j; n :=
StringTools:-Length(str); C := []; S := []; for i to k do
C[i] := seq(str[i+j*k], j = 0 .. floor((n-i)/k)); S[i] :=
cat(op(C[i])) end do; return S end proc
Error, attempting to assign to `StringTools:-CharacterFrequencies` which is protected
FindShift := proc (F1, F2) local i, s, n, t, S, M; n :=
nops(F1); t := nops(F2); S := []; for s from 0 to n-1 do
S[s+1] := add((F1[i]-F2[(`mod`(i+s, t))+1])^2, i = 1 .. n)
end do; M := minloc(S); return M[2]-1 end proc
Error, (in Subsequences) expression sequences cannot be assigned to lists
F :=
Error, invalid input: FindShift uses a 2nd argument, F2, which is missing
KeyLetters := Number2Letter(Shifts, "abcdefghijklmnopqrstuvwxyz")
Key := Shiftsabcdefghijklmnopqrstuvwxyz
e) Decipher cstr using the key found in (d) and your DecryptVigenere routine from question 2. Note that the encrypted text will have blanks removed.
with(StringTools);
[Anagrams, AndMap, ApproximateSearch, ApproximateSearchAll,
ArithmeticMean, Border, BorderArray, BorderLength, CamelCase,
Capitalize, CaseJoin, CaseSplit, Center, Centre, Char,
CharacterFrequencies, CharacterMap, Chomp, Chop, CommonPrefix,
CommonSuffix, Compare, CompareCI, Compress,
CountCharacterOccurrences, Decode, DecodeEntities, Delete,
DeleteSpace, DifferencePositions, Drop, EditDistance, Encode,
EncodeEntities, Entropy, Escape, Exchange,
ExpandCharacterClass, ExpandTabs, Explode, Fence, Fibonacci,
Fill, FirstFromLeft, FirstFromRight, FormatMessage, FormatTime,
FromByteArray, Generate, GenerateIdentifier, Group,
HammingDistance, HammingSearch, HammingSearchAll, Has,
HasASCII, HasAlpha, HasAlphaNumeric, HasBinaryDigit,
HasControlCharacter, HasDigit, HasGraphic, HasHexDigit,
HasIdentifier, HasIdentifier1, HasLower, HasOctalDigit,
HasPrintable, HasPunctuation, HasSpace, HasUpper, HasVowel,
Hash, Implode, Indent, IndexOfCoincidence, Insert, Iota,
IsASCII, IsAlpha, IsAlphaNumeric, IsAnagram, IsBalanced,
IsBinaryDigit, IsConjugate, IsControlCharacter, IsDerangement,
IsDigit, IsEodermdrome, IsGraphic, IsHexDigit, IsIdentifier,
IsIdentifier1, IsLower, IsMonotonic, IsOctalDigit,
IsPalindrome, IsPeriod, IsPermutation, IsPrefix, IsPrimitive,
IsPrintable, IsPunctuation, IsSorted, IsSpace, IsSubSequence,
IsSuffix, IsUpper, IsVowel, Join, Kasiski, LeftFold,
LeftRecursivePathOrder, Length, LengthSplit, Levenshtein,
LexOrder, LongestCommonSubSequence, LongestCommonSubString,
LowerCase, LyndonFactors, Map, MatchFence, MaxChar,
MaximalPalindromicSubstring, Metaphone, MinChar,
MinimumConjugate, MonotonicFactors, NGrams, NthWord, OrMap,
Ord, OtherCase, Overlap, PadLeft, PadRight, ParseTime,
PatternCanonicalForm, PatternDictionary, PatternEquivalent,
Period, Permute, PrefixDistance, PrimitiveRoot, Random,
Randomize, Readability, RegMatch, RegSplit, RegSub, RegSubs,
Remove, Repeat, Repeats, RevLexOrder, Reverse, RightFold,
RightRecursivePathOrder, Rotate, Search, SearchAll, Select,
SelectRemove, Sentences, Shift, ShortLexOrder,
ShortRevLexOrder, SimilarityCoefficient, Snarf, Sort,
SortPermutation, Soundex, Split, Squeeze, Stem, StringBuffer,
StringSplit, SubString, Subs, Substitute, SubstituteAll,
SuffixDistance, Support, SyllableLength, Tabulate, Take,
ThueMorse, ToByteArray, Trim, TrimLeft, TrimRight, Uncompress,
Unique, UpperCase, Visible, WildcardMatch, WordContaining,
WordCount, WordEnd, WordStart, Words, WrapText]
alphabet := "abcdefghijklmnopqrstuvwxyz";
alphabet := "abcdefghijklmnopqrstuvwxyz"
cstr := "eqjyvxvgiuphmrrrgzhvwrrukmrtijfbtodidtsjsgofwmfalkeveolqlmhkfhrerhwuidejonvjuumklhliiwwnajxbonjthitzsqufklhihrvditvvvzhvwhihrvditvvvgsrrbunvqlmhkvhgdzpbmuvwvloiqdiiglhxtyewosksvgyklhecfrykyrqhgnzrjhukxkknwvrswyewosbrrcnfjnodumfuuchqutjysvojikomtesgbcirlcfrvzrlgwonxeqeowxkkmfvhgbjxuasvguepksjxaglvomrhhapdcponuewuntiwnakxkosnevufrwlspcivvetmhyslgknoniykrrwzuuchdvpveuzoklhirlhhonkioretxrltyivgicsugbjsoatvpbonjsoabcizotysxztyinky";
cstr := "eqjyvxvgiuphmrrrgzhvwrrukmrtijfbtodidtsjsgofwmfalkeveol\
qlmhkfhrerhwuidejonvjuumklhliiwwnajxbonjthitzsqufklhihrvditvvv\
zhvwhihrvditvvvgsrrbunvqlmhkvhgdzpbmuvwvloiqdiiglhxtyewosksvgy\
klhecfrykyrqhgnzrjhukxkknwvrswyewosbrrcnfjnodumfuuchqutjysvoji\
komtesgbcirlcfrvzrlgwonxeqeowxkkmfvhgbjxuasvguepksjxaglvomrhha\
pdcponuewuntiwnakxkosnevufrwlspcivvetmhyslgknoniykrrwzuuchdvpv\
euzoklhirlhhonkioretxrltyivgicsugbjsoatvpbonjsoabcizotysxztyin\
ky"
Key := [19, 4, 18, 19];
Key := [19, 4, 18, 19]
DecryptVigenere := proc(str,key,alphabet)
local i, n, m, L, K, C, Convert, plain;
Convert := table(); n := StringTools:-Length(alphabet);
for i from 1 to n do
Convert[alphabet[i]] := i-1;
end do;
L := Letter2Number(str,Convert);
K := Letter2Number(key,Convert);
m := nops(K);
C := [];
for i from 1 to nops(L) do
C := [op(C),L[i]-K[i mod m + 1] mod n];
end do;
plain := Number2Letter(C,alphabet);
return plain;
end;
DecryptVigenere := proc (str, key, alphabet) local i, n, m, L,
K, C, Convert, plain; Convert := table(); n := StringTools:-L\
ength(alphabet); for i to n do Convert[alphabet[i]] := i-1
end do; L := Letter2Number(str, Convert); K := Letter2Number(\
key, Convert); m := nops(K); C := []; for i to nops(L) do C
:= [op(C), `mod`(L[i]-K[(`mod`(i, m))+1], n)] end do; plain
:= Number2Letter(C, alphabet); return plain end proc
DecryptVigenere(cstr,Key,alphabet);
Number2Letter([Letter2Number("eqjyvxvgiuphmrrrgzhvwrrukmrtijfbto\
didtsjsgofwmfalkeveolqlmhkfhrerhwuidejonvjuumklhliiwwnajxbonjt\
hitzsqufklhihrvditvvvzhvwhihrvditvvvgsrrbunvqlmhkvhgdzpbmuvwvl\
oiqdiiglhxtyewosksvgyklhecfrykyrqhgnzrjhukxkknwvrswyewosbrrcnf\
jnodumfuuchqutjysvojikomtesgbcirlcfrvzrlgwonxeqeowxkkmfvhgbjxu\
asvguepksjxaglvomrhhapdcponuewuntiwnakxkosnevufrwlspcivvetmhys\
lgknoniykrrwzuuchdvpveuzoklhirlhhonkioretxrltyivgicsugbjsoatvp\
bonjsoabcizotysxztyinky", Convert)[1]
+ 25 Letter2Number([19, 4, 18, 19], Convert)[2], Letter2Number("eqjyvxvgiuphmrrrgzhvwrrukmrtijfbtodidtsjsgofwmfalkeveolqlmhkfhrerhwuidejonvjuumklhliiwwnajxbonjthitzsqufklhihrvditvvvzhvwhihrvditvvvgsrrbunvqlmhkvhgdzpbmuvwvloiqdiiglhxtyewosksvgyklhecfrykyrqhgnzrjhukxkknwvrswyewosbrrcnfjnodumfuuchqutjysvojikomtesgbcirlcfrvzrlgwonxeqeowxkkmfvhgbjxuasvguepksjxaglvomrhhapdcponuewuntiwnakxkosnevufrwlspcivvetmhyslgknoniykrrwzuuchdvpveuzoklhirlhhonkioretxrltyivgicsugbjsoatvpbonjsoabcizotysxztyinky",
Convert)[2] + 25 Letter2Number([19, 4, 18, 19], Convert)[1]],
"abcdefghijklmnopqrstuvwxyz")
f) Decipher the Vigenere ciphers from Computer Problems 8 and 9 from Section 2.14 of the text.
xkju:= "xkjurowmllpxwznpimbvbqjcnowxpcchhvvfvsllfvxhazityxohulxqojaxelxzxmyjaqfs\
tsrulhhucdskbxknjqidallpqslluhiaqfpbpcidsvcihwhwewthbtxrljnrsncihuvffuxvoukjlj\
swmaqfvjwjsdyljogjxdboxajultucpzmpliwmlubzxvoodybafdskxgqfadshxnxehsaruojaqfpf\
kndhsaafvulluwtaqfrupwjrszxgpfutjqiynrxnyntwmhcukjfbirzsmehhsjshyonddzzntzmpli\
lrwnmwmlvuryonthuhabwnvw";
ocwy:= "ocwyikoooniwugpmxwktzdwgtssayjzwyemdlbnqaaavsuwdvbrflauplooubfgqhgcscmgz\
latoedcsdeidpbhtmuovpiekifpimfnoamvlpqfxejsmxmpgkccaykwfzpyuavtelwhrhmwkbbvgtg\
uvtefjlodfefkvpxsgrsorvgtajbsauhzrzalkwuowhgedefnswmrciwcpaaavogpdnfpktdbalsis\
urlnpsjyeatcuceesohhdarkhwotikbroqrdfmzghgucebvgwcdqxgpbgqwlpbdaylooqdmuhbdqgm\
yweuik";
xkju := "xkjurowmllpxwznpimbvbqjcnowxpcchhvvfvsllfvxhazityxohulx\
qojaxelxzxmyjaqfstsrulhhucdskbxknjqidallpqslluhiaqfpbpcidsvcih\
whwewthbtxrljnrsncihuvffuxvoukjljswmaqfvjwjsdyljogjxdboxajultu\
cpzmpliwmlubzxvoodybafdskxgqfadshxnxehsaruojaqfpfkndhsaafvullu\
wtaqfrupwjrszxgpfutjqiynrxnyntwmhcukjfbirzsmehhsjshyonddzzntzm\
plilrwnmwmlvuryonthuhabwnvw"
ocwy := "ocwyikoooniwugpmxwktzdwgtssayjzwyemdlbnqaaavsuwdvbrflau\
plooubfgqhgcscmgzlatoedcsdeidpbhtmuovpiekifpimfnoamvlpqfxejsmx\
mpgkccaykwfzpyuavtelwhrhmwkbbvgtguvtefjlodfefkvpxsgrsorvgtajbs\
auhzrzalkwuowhgedefnswmrciwcpaaavogpdnfpktdbalsisurlnpsjyeatcu\
ceesohhdarkhwotikbroqrdfmzghgucebvgwcdqxgpbgqwlpbdaylooqdmuhbd\
qgmyweuik"