nospace := proc(sentence) local i, nsent; nsent := "": for i from 1 to length(sentence) do if substring(sentence, i) <> " " then nsent := cat(nsent, substring(sentence, i)); fi: od: end: inspace := proc(sentence, bl) local i, j, nsent; nsent := ""; for i from 1 to length(sentence) do if (i) mod bl <> 0 then nsent := cat(nsent, substring(sentence, i)); else nsent := cat(nsent, substring(sentence, i)); nsent := cat(nsent, " "); fi: od: end: shiftamount := proc(fromletter, toletter) local abet, shift; abet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; shift := (SearchText(toletter, abet) - SearchText(fromletter,abet)) mod 26; end: strgraph := proc(mess, sl, info) local i, j, k, str1, ct, str2, strset, olist, dlist, pos, gcddlist, flist: strset := {}: flist := []: for i from 1 to length(mess)-sl+1 do ct := 1: olist := [i]: dlist := []: pos := i: gcddlist := 0; str1 := substring(mess, i..i+sl-1): if not member(str1, strset) and searchtext(" ", str1) = 0 then for j from i+sl to length(mess)-sl+1 do str2 := substring(mess, j..j+sl-1): if str1=str2 then olist := [op(olist), j]; dlist := [op(dlist), j-pos]; pos := j: ct := ct + 1: fi: od: if ct > 1 then gcddlist := igcd(seq(dlist[k], k = 1..nops(dlist))); fi: fi: if ct >= 2 and not member(str1, strset) then if info = true then flist := [op(flist), [cat(convert(sl, string)," graph ", str1 ," occurs ", convert(ct, string) ," times at positions ",convert(olist, string), " at distances ",convert(dlist, string),". " , "Prime dlist = ",convert(map(ifactor, dlist), string), ". ", "Gcd of distances = ", convert(gcddlist,string)), ct]]; else flist := [op(flist), [cat(convert(sl, string), " graph ",str1, " occurs ", convert(ct, string)," times"), ct]]; fi: fi: strset := strset union {str1}: od: flist := sort(flist, (x,y) -> evalb(x[2] > y[2])); seq(lprint(flist[i][1]), i = 1..nops(flist)); end: shiftcipher := proc(mess, shift, type) local letters, ltable, i, j, rmess, lmess; letters := array(0..25, ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]): ltable := table(): for i from 0 to 25 do ltable[ letters[i] ] := i: od: rmess := "": lmess := convert(mess, list); if type = 'encipher' then for i from 1 to length(mess) do rmess := cat(rmess, letters[ (ltable[ lmess[i] ] + shift) mod 26 ]); od: elif type = 'decipher' then for i from 1 to length(mess) do rmess := cat(rmess, letters[ (ltable[ lmess[i] ] - shift) mod 26 ]); od: else lprint("third parameter must be encipher or decipher"): fi: rmess; end: affinecipher := proc(mess, a, b, type) local letters, ltable, i, j, rmess, lmess; letters := array(0..25, ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]): if gcd(a,26) <> 1 then RETURN(lprint(cat("gcd of multiplication parameter ", convert(a, string), " and 26 = ", convert(gcd(a,26), string), ". The gcd must be 1."))); end: ltable := table(): for i from 0 to 25 do ltable[ letters[i] ] := i: od: rmess := "": lmess := convert(mess, list); if type = 'encipher' then for i from 1 to length(mess) do rmess := cat(rmess, letters[ (a*ltable[ lmess[i] ] + b) mod 26 ]); od: elif type = 'decipher' then for i from 1 to length(mess) do rmess := cat(rmess, letters[ a^(-1)*(ltable[ lmess[i] ] - b) mod 26 ]); od: else lprint("third parameter must be encipher or decipher"): fi: rmess; end: rdup := proc(key) local i, nkey, skey; nkey := ""; skey := convert(convert(key,list), set); for i from 1 to length(key) do if member(key[i],skey) then nkey := cat(nkey, key[i]): skey := skey minus {key[i]}; fi: od: RETURN(nkey): end: keywordcoltrans := proc(message, keyword, ctype) local key, p, i, answer, mess, r, q, c, n, j, column, nmess; mess := message; c := length(keyword); n := length(message); r := n mod c; if r <> 0 then mess := cat(mess, seq("X", i = 1..(c-r))); lprint("Message length is not a multiple of keyword length."); lprint("X's will be padded to end of message."); fi: key := rdup(cat(seq(sort(convert(keyword, list))[i], i = 1..c))); p := [seq( StringTools[SearchAll](key[i],keyword), i = 1..c ) ]; print(p); q := n/c; print(p); print(q); # answer := array(1..5); nmess := ""; if ctype = 'encipher' then # for j from 1 to c do # print( (q*(p(j)-1)+1) ); print(q*p(j)); # column := cat(seq(mess[((i-1) mod q)*c+iquo((i-1),q) + 1], i = (q*(p[j]-1)+1)..q*p[j])); # answer := cat(answer, column); # od: elif ctype = 'decipher' then # for j from 1 to c do # print( (q*(p[j]-1)+1) ); print(q*p[j]); # column := cat(seq(mess[((i-1) mod c)*q+iquo((i-1),c) + 1], i = (q*(p[j]-1)+1)..q*p[j])); # print(column); # answer := cat(answer, column); # answer[j] := column; # od: for j from 1 to c do column := substring(mess, q*(p[j]-1)+1..q*p[j]); nmess := cat(nmess, column); od: print(nmess); answer := cat(seq(nmess[((i-1) mod c)*q+iquo((i-1),c) + 1], i = 1..n)) else lprint("third parameter must be encipher or decipher"): fi: print(answer); end: vigenere := proc(message, keyword, ctype) local i, j, otext, messct, keyct, letters, ltable, vtable; letters := array(0..25, ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]): ltable := table(): for i from 0 to nops(convert(letters, list)) - 1 do ltable[ letters[i] ] := i: od: vtable := table(): for i from 0 to nops(convert(letters, list)) - 1 do for j from 0 to nops(convert(letters, list)) - 1 do vtable[ letters[i], letters[j] ] := letters[ (i+j) mod 26 ]: od: od: otext := ""; if ctype = 'encipher' then messct := 0; while messct < length(message) do keyct := 0: while (keyct < length(keyword)) and (messct < length(message)) do keyct := keyct + 1: messct := messct + 1: otext := cat(otext, vtable[substring(keyword,keyct), substring(message, messct)]); od: od: elif ctype = 'decipher' then messct := 0; while messct < length(message) do keyct := 0: while (keyct < length(keyword)) and (messct < length(message)) do keyct := keyct + 1: messct := messct + 1: otext := cat(otext, letters[ ( ltable[ substring(message, messct) ] - ltable[ substring(keyword, keyct) ]) mod 26 ]): od: od: else lprint("third parameter must be encipher or decipher"): fi: RETURN(otext); end: vigenkey := proc(ptext, ctext) vigenere(ctext,ptext,decipher); end: ic := proc(mess) local i, j, letterct, lsum, alphabet, nmess, ncoin , fl; alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; ncoin := 0; nmess := mess; for i from 1 to length(alphabet) do lsum := 0; fl := SearchText(substring(alphabet, i), nmess); while fl <> 0 do lsum := lsum + 1; nmess := cat(substring(nmess, 1..fl-1), substring(nmess, fl+1..length(nmess))); fl := SearchText(substring(alphabet, i), nmess); od: ncoin := ncoin + lsum*(lsum-1); od: RETURN(ncoin/(length(mess)*(length(mess) - 1))); end: vigencoset := proc(kwl, mess) local i, monolist, pos, bstr; monolist := []; for i from 1 to kwl do pos := i: bstr := ""; while substring(mess, pos) <> "" do bstr := cat(bstr, substring(mess, pos)); pos := pos + kwl; od: monolist := [op(monolist), bstr]: od: RETURN(monolist); end: keyletters := proc(keylist) local i, keystring; keystring := convert(cat(seq(keylist[i], i = 1..nops(keylist))), list); linalg[transpose](matrix(nops(keylist), length(keylist[1]), keystring)); end: letterdist := proc(message) local i, j, r, s, t, freq, pa, alphabet, pt; freq := length(message)*letterfreq(message); pa := array(1..nops(freq)); alphabet := [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z]; for i from 1 to nops(freq) do if freq[i] <> 0 then pa[i] := plot([[i-0.5, r, r = 0..freq[i]], [s, freq[i], s = i-0.5..i+0.5], [i+0.5, t, t = 0..freq[i]]], color = black): else pa[i] := plots[pointplot]([i,0]): fi: od: pt:= plots[textplot]([ seq([i, -1, alphabet[i]], i = 1..nops(alphabet)) ]): plots[display]([seq(pa[i], i = 1..nops(freq)), pt], color = black, thickness = 2, xtickmarks=0); end: signature := proc(flist) local sflist, i; sflist := sort(flist); plots[pointplot]([ seq([i, sflist[i]], i = 1..nops(sflist)) ], connect = true); end: shiftletter := proc(anumber) local alphabet; alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; substring(alphabet, anumber+1); end: scrawl := proc(flist) local i, alphabet, p1, p2; alphabet := [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z]; p1 := plots[pointplot]([ seq([i, flist[i]], i = 1..nops(flist)) ], connect = true, color = red, thickness = 3): p2:= plots[textplot]([ seq([i, -.003, alphabet[i]], i = 1..nops(alphabet)) ]): plots[display]([p1,p2], xtickmarks = 0, title = "Scrawl for given frequency distribution"); end: fscrawl := proc(flist, shift, clr, thickv) local i, j, nlist, alphabet, p1, p2; alphabet := [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z]; nlist := [seq(flist[i], i = 1+shift..nops(flist)), seq(flist[j], j = 1..shift) ]: p1 := plots[pointplot]([ seq([i, nlist[i]], i = 1..nops(nlist)) ], connect = true, color = clr, thickness = thickv): p2:= plots[textplot]([ seq([i, -.003, alphabet[i]], i = 1..nops(alphabet)) ]): plots[display]([p1,p2], xtickmarks = 0): end: ascrawl := proc(coset) local i, elist, flist: elist := [.08167, 0.01492, 0.02782, 0.04253, 0.12702, 0.02228, 0.02015, 0.06094, 0.06966, 0.00153, 0.00772, 0.04025, 0.02406, 0.06749, 0.07507, 0.01929, 0.00095, 0.05987, 0.06327, 0.09056, 0.02758, 0.00978, 0.02360, 0.00150, 0.01974, 0.00074]; flist := letterfreq(nospace(coset)); plots[display](seq(display([fscrawl(elist, 0, red, 3), fscrawl(flist, i, blue, 1)], title = cat("left shift = ", convert(i, string))), i = 0..25), insequence = true); end: letterfreq := proc(mess) local i, abet, flist, ct, j: flist := []: abet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for i from 1 to length(abet) do ct := 0: for j from 1 to length(mess) do if evalb(substring(abet,i) = substring(mess, j)) then ct := ct + 1 fi: od: flist := [op(flist), ct]: od: flist := flist/length(mess): end: printletterfreq := proc(mess) local i, abet, alist; abet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; alist := length(mess)*letterfreq(mess); for i from 1 to length(abet) do lprint(cat("Letter ", substring(abet,i), " occurs ", convert(alist[i], string), " times.")); od: end: cosetsign := proc(ctext, cl) local fkey, p1, p2, elist; elist := sort([.08167, 0.01492, 0.02782, 0.04253, 0.12702, 0.02228, 0.02015, 0.06094, 0.06966, 0.00153, 0.00772, 0.04025, 0.02406, 0.06749, 0.07507, 0.01929, 0.00095, 0.05987, 0.06327, 0.09056, 0.02758, 0.00978, 0.02360, 0.00150, 0.01974, 0.00074]); fkey := vigencoset(cl, ctext): p1 := plots[display]([seq(display(signature(letterfreq(sort(fkey[i])))), i = 1..cl)], color = black, thickness = 1): p2 := display(signature(elist), color = red, thickness = 3): plots[display]([p1,p2], title = cat("Signature for coset length ", convert(cl, string))); end: cosetdata := proc(mess, l) local i, j, k, V, A, coset, lfreq; coset := mlist(l, mess): for j from 1 to l do lfreq := evalf(sort(letterfreq(coset[j]))); V[j] := 1/2*add(k,k = [seq(lfreq[i] + lfreq[i-1], i = 14..26)]) - add(k,k = [seq(lfreq[i] + lfreq[i-1], i = 2..14)]); od: A := 0; for j from 1 to l do A := A + V[j]; od: A := evalf(A/l); end: scrawldata := proc(ctext, kwl) local i, j, k, sv, shiftl, efreq, flist, dlist, coset, s; efreq := [.08167, 0.01492, 0.02782, 0.04253, 0.12702, 0.02228, 0.02015, 0.06094, 0.06966, 0.00153, 0.00772, 0.04025, 0.02406, 0.06749, 0.07507, 0.01929, 0.00095, 0.05987, 0.06327, 0.09056, 0.02758, 0.00978, 0.02360, 0.00150, 0.01974, 0.00074]; coset := mlist(kwl, ctext): for i from 1 to kwl do dlist := []: flist := evalf(letterfreq(coset[i])); for sv from 0 to 25 do shiftl := [seq(flist[j], j = sv+1..26), seq(flist[j], j = 1..sv)]; dlist := [op(dlist), evalf(linalg[dotprod](efreq, shiftl),3)]; od: member(evalf(max(seq(dlist[i], i = 1..nops(dlist))),3), dlist, 's'); print(cat("Scrawl for shift for coset ", convert(i,string), " is "), dlist, "Max = ", evalf(max(seq(dlist[i], i = 1..nops(dlist))),3), "at shift value ", s-1); od: end: csubsetup := proc(message) local i, j, subc; subc := linalg[matrix](2, length(message)); for j from 1 to length(message) do subc[1,j] := convert(substring(message, j), symbol); subc[2,j] := convert(" ", symbol); od: for i from 1 to linalg[coldim](subc) by 26 do if (i + 26 - 1) > linalg[coldim](subc) then print(linalg[augment](linalg[col](subc,i..linalg[coldim](subc)))); else print(linalg[augment](linalg[col](subc,i..i+26-1))); fi: print(" "); od: RETURN(evalm(subc)): end: subcipher := proc(fromletter, toletter, ctextm) local subc, j, i; subc := ctextm; for j from 1 to linalg[coldim](subc) do if convert(subc[1,j], string) = fromletter then subc[2,j] := convert(toletter, symbol): fi: od: for i from 1 to linalg[coldim](subc) by 25 do if (i + 25 - 1) > linalg[coldim](subc) then print(linalg[augment](linalg[col](subc,i..linalg[coldim](subc)))); else print(linalg[augment](linalg[col](subc,i..i+25-1))); fi: print(" "); od: RETURN(evalm(subc)): end: asubsetup := proc(abet) local i, j, suba; suba := linalg[matrix](2, length(abet)); for j from 1 to length(abet) do suba[2,j] := convert(substring(abet, j), symbol); suba[1,j] := convert(" ", symbol); od: print(evalm(suba)); RETURN(evalm(suba)): end: subabet := proc(fromletter, toletter, abetm) local suba, j, i; suba :=abetm; if toletter <> " " then for j from 1 to linalg[coldim](suba) do if convert(suba[2,j], string) = toletter then suba[1,j] := convert(fromletter, symbol): fi: od: elif toletter = " " then for j from 1 to linalg[coldim](suba) do if convert(suba[1,j], string) = fromletter then suba[1,j] := convert(" ", symbol): fi: od: fi: RETURN(evalm(suba)); end: tonumber := proc(mess) local sl, cn, sn, ii: sl := length(mess); cn := 0; for ii from 1 to sl do sn := StringTools[Ord](substring(mess, ii..ii)): if sn >= 100 then cn := 1000*cn + sn: else cn := 100*cn + sn: fi: od: RETURN(cn): end: toletter := proc(num) local cs, cn, sl, ans, i, tst; cn := num; sl := floor(trunc(evalf(log10(cn)))/2) + 1: ans := ""; for i from 1 to sl do tst := cn/1000: if (frac(tst)*1000 >= 100) and (frac(tst)*1000 <= 127) then cn := cn/1000; cs := StringTools[Char](frac(cn)*1000); ans := cat(cs, ans); cn := trunc(cn); else cn := cn/100; cs := StringTools[Char](frac(cn)*100); ans := cat(cs, ans); cn := trunc(cn); fi: od: RETURN(ans); end: mblocks := proc(message, bl) local messblocks; messblocks := [seq(substring(message,(i-1)*bl+1..i*bl),i=1..iquo(length(message),bl)+1)]; end: rsa := proc(messnum, exponent, modulus) local z; z := map(messnum -> messnum &^ exponent mod modulus, messnum); end: lnum := proc(num) length(convert(num, string)); end: