> with(LinearAlgebra): with(linalg): with(numtheory): with(plots): > numb:=table([" "=0,"a"=1, "b"=2, "c"=3, "d"=4, "e"=5, "f"=6, "g"= 7, "h"=8, "i"=9, "j"=10, "k"=11, "l"=12, "m"=13, "n"=14, "o"=15, "p"=16, "q"=17, "r"=18, "s"=19, "t"=20, "u"=21, "v"=22, "w"=23, "x"=24, "y"=25, "z"=26]): > alph:=table([0=" ",1="a",2="b",3="c",4="d",5="e",6="f",7="g",8= "h",9="i",10="j",11="k",12="l",13="m",14="n",15="o",16="p",17= "q",18="r",19="s",20="t",21="u",22="v",23="w",24="x",25="y",26= "z"]): > shift:=proc(txt,n) > local i, z; > z :=NULL; > for i from 1 while i<= length(txt) do > z:=cat(z,(alph[(numb[substring(txt,i)]+n-1 mod 26)+1])); > end do; > return(z); > end: > allshifts:= proc(txt) > local i; > for i from 0 while i<26 do > print(shift(txt,i)); > end do; > end: > affinecrypt:= proc(txt,m,n) > local i,z; > z:=NULL; > for i from 1 while i<=length(txt) do > z:=cat(z,(alph[((numb[substring(txt,i)]-1)*m+n mod 26)+1])); > end do; > return(z); > end: > vigenere:= proc(txt,v) > local i,z; > z:=NULL; > for i from 1 while i<=length(txt) do > z:=cat(z,alph[(numb[substring(txt,i)]+v[(i-1 mod nops(v))+1] -1 mod 26)+1]); > end do; > return(z); > end: > choose:=proc(txt,m,n) > local i,z; > z:=NULL; > for i from n by m while i<= length(txt) do > z:=cat(z,substring(txt,i)); > end do; > return(z); > end: > frequency:=proc(txt) > local i,j,k,v,z; z:=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0]; > for i from 1 while i<= length(txt) do > j:=numb[substring(txt,i)]; > z:=subsop(j=z[j]+1,z); > end do; > return(z); > end: > vigvec:= proc(txt,m,n) > local w,z,i; > z:=choose(txt,m,n); > w:=frequency(z)/length(z)*1.; > return(w); > end: > alfreq:=[.082, .015, .028, .043, .127, .022, .020, .061, .070, .002, .008, .040, .024, .067, .075, .019, .001, .060, .063, .091, .028, .010, .023, .001, .020, .001]: > corr:=proc(v) > local i,j,w,z; > w:=augment(matrix(1,26,v),matrix(1,26,v)); > z:=seq(sum(alfreq[i]*w[1,i+j-1],i=1..26),j=1..26); > return(z); > end: > coinc:=proc(txt,s) > local i,w,z; > z:=0; > for i from 1 while i <= length(txt)-s do > if substring(txt,i)=substring(txt,i+s) then z:=z+1 else z:=z fi; > end do; > return(z); > end: > lfsr:=proc(c,k,n) > local f,i,j,r,z; > z:=matrix(1,nops(k),k); > for i from 1 while i<= n-nops(c) do > z:=augment(z,matrix(1,1,[sum(z[1,j+i-1]*c[j],j=1..nops(c)) mod 2] )); > end do; > z:=row(z,1);z:=[seq(z[i],i=1..n)]; > end: > lfsrlength:=proc(v,n) > local w,z,i,j,k; > for k from 1 while k<=n do > w:=array(1..k,1..k); > for i from 1 while i<= k do > for j from 1 while j<= k do > w[i,j]:=v[i+j-1]; > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > end do; end do; print([k,det(w) mod 2]); end do; end: lfsrsolve:=proc(v,n) local w1,w,z,i,j,k; w1:=array(1..n,1..1); w:=array(1..n,1..n); for i from 1 while i<= n do for j from 1 while j<= n do w[i,j]:=v[i+j-1]; end do; end do; for i from 1 while i<= n do w1[i,1]:=v[i+n]; end do; z:=evalm(det(w)*transpose(evalm(inverse(w)&*w1))); z:=map(x->x mod 2,z); z:=[seq(z[1,i],i=1..n)]; z; end: text2num:=proc(txt) local i,z; z:=0; for i from 1 while i<=length(txt) do z:=100*z+numb[substring(txt,i)]; end do; return(z); end: num2text:=proc(n) local i,w,z; z:=NULL;w:=n; for i from 1 while 100^(i-1)<n do z:=cat(alph[w mod 100],z); w:=floor(w/100); end do; return(z); end: cards:=[200514,10010311,1721050514,11091407,10305]: with(combinat,randperm): khide:=proc();2*rand()+101;end: shuffle:=proc(k) local z; z:=randperm({cards[1]&^k,cards[2]&^k,cards[3]&^k,cards[4]&^k, cards[5]&^k}mod 24691313099); return(z); end: reveal:=proc(c) local k1,z; k1:= k&^(-1) mod 24691313098; z:=[c[1]&^k1,c[2]&^k1,c[3]&^k1,c[4]&^k1,c[5]&^k1] mod > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > 24691313099; z:=[num2text(z[1]),num2text(z[2]),num2text(z[3]),num2text(z[4]), num2text(z[5])]; return(z); end: advise:=proc(v) local i,w,z; w:=1; for i from 1 while w=1 do w:=v[i]&^((24691313099-1)/2) mod 24691313099; end do; return(i-1); end: addell:=proc(p1,p2,a,b,n) local z,z1,m,x3,y3,p3; z:=0; z1:=1; if p1=["infinity","infinity"] then p3:=p2; z:=1 else end if; if z=1 then NULL else if p2=["infinity","infinity"] then p3:=p1; z:=1 else end if end if; if z=1 then NULL else if p1[1]=p2[1] and p1[2]=0 then p3:=["infinity","infinity"]; z:=1 else end if end if; if z=1 then NULL else if p1[1]=p2[1] and p1[2]<>p2[2] then p3:=["infinity","infinity"]; z:=1 else end if end if; if z=1 then NULL else if p1=p2 and gcd(p1[2],n)<>1 and gcd(p1[2],n)<>n then z1:=gcd(p1[2],n); z:=1 else end if end if; if z=1 then NULL else if p1=p2 then m:=((3*p1[1]^2+a)*((2*p1[2])&^(-1) mod n)) mod n; z:=1; x3:=(m^2-p1[1]-p2[1]) mod n; y3:=(m*(p1[1]-x3)-p1[2]) mod n; p3:=[x3,y3]; else end if end if; if z=1 then NULL else if gcd(p2[1]-p1[1],n)<>1 then z:=1;z1:=gcd(p2[1]-p1[1],n) else end if end if; if z=1 then NULL else m:= ((p2[2]-p1[2])*((p2[1]-p1[1])&^(-1) mod n)) mod n; x3:=(m^2-p1[1]-p2[1]) mod n; y3:= (m*(p1[1]-x3)-p1[2]) mod n; p3:= [x3,y3] end if; if z1=1 then return(p3) else return(["factor=",z1]) end if; end: multsell:=proc(p1,m,a,b,n) local i,z; > > > > > > > > > > > > > > > > > > > > > z:=[[1,p1]]; for i from 2 while i<=m and z[-1][2][1]<>"factor=" do z:=[op(z),[1+nops(z),addell(p1,z[nops(z)][2],a,b,n)]]; end do; return(z); end: multell:=proc(p,m,a,b,n) local i,j,q,y,z1; y:=["infinity","infinity"]; q:=p; z1:=m; for i from 1 while z1<>0 and y[1]<>"factor=" do for j from 1 while z1 mod 2 = 0 and q[1]<>"factor=" do z1:=z1/2; q:=addell(q,q,a,b,n); end do; z1:=z1-1; y:=addell(q,y,a,b,n); end do; if q[1]="factor=" then y:=q else NULL end if; return(y); end: gaul:= "gaulisdividedintothreeparts": ycve:= "ycvejqwvhqtdtwvwu": edsg:= "edsgickxhuklzveqzvkxwkzukcvuh": tcab:= "tcabtiqmfheqqmrmvmtmaq": lcll:= "lcllewljazlnnzmvyiylhrmhza": DNA:= "GAATTCGCGGCCGCAATTAACCCTCACTAAAGGGATCTCTAGAACT": > xkju:= "xkjurowmllpxwznpimbvbqjcnowxpcchhvvfvsllfvxhazityxohulxqojaxelxz xmyjaqfs\ tsrulhhucdskbxknjqidallpqslluhiaqfpbpcidsvcihwhwewthbtxrljnrsncih uvffuxvoukjlj\ swmaqfvjwjsdyljogjxdboxajultucpzmpliwmlubzxvoodybafdskxgqfadshxnx ehsaruojaqfpf\ kndhsaafvulluwtaqfrupwjrszxgpfutjqiynrxnyntwmhcukjfbirzsmehhsjshy onddzzntzmpli\ lrwnmwmlvuryonthuhabwnvw": ocwy:= "ocwyikoooniwugpmxwktzdwgtssayjzwyemdlbnqaaavsuwdvbrflauplooubfgq hgcscmgz\ latoedcsdeidpbhtmuovpiekifpimfnoamvlpqfxejsmxmpgkccaykwfzpyuavtel whrhmwkbbvgtg\ uvtefjlodfefkvpxsgrsorvgtajbsauhzrzalkwuowhgedefnswmrciwcpaaavogp dnfpktdbalsis\ urlnpsjyeatcuceesohhdarkhwotikbroqrdfmzghgucebvgwcdqxgpbgqwlpbday looqdmuhbdqgm\ yweuik": > hdsf:= "hdsfgvmkoowafweetcmfthskucaqbilgjofmaqlgspvatvxqbiryscpcfrmvswrv nqlszd\ > mgaoqsakmlupsqforvtwvdfcjzvgsoaoqsacjkbrsevbelvbksarlscdcaarmnvry sywxqgvellcyl\ uwwveoafgclazowafojdlhssfiksepsoywxafowlbfcsocylngqsyzxgjbmlvgrgg okgfgmhlmejab\ sjvgmlnrvqzcrggcrghgeupcyfgtydycjkhqluhgxgzovqswpdvbwsffsenbxapas gazmyuhgsfhmf\ tayjxmwznrsofrsoaopgauaaarmftqsmahvqecev": vvhq:= "vvhqwvvrhmusgjgthkihtssejchlsfcbgvwcrlryqtfsvgahwkcuhwauglqhnslr ljshbl\ tspisprdxljsveeghlqwkasskuwepwqtwvspgoelkcqyfnsvwljsniqkgnrgybwlw goviokhkazkqk\ xzgyhcecmeiujoqkwfwvefqhkijrclrlkbienqfrjljsdhgrhlsfqtwlauqrhwdmw lgusgikkflryv\ cwvspgpmlkassjvoqxeggveyggzmljcxxljsvpaivwikvrdrygfrjljslveggveyg geiapuuisfpbt\ gnwwmuczrvtwglrwugumnczvile": vpln:= "thefirstfibonaccinumberisonethesecondfibonaccinumberisonethethir distwoth\ efourthisthreethefifthisfiveandsooneachisthesumofthetwopreviousnu mbersandinthis\ waywecanfindthatthefiftiethfibonaccinumberistwelvebillionfivehund redeightysixmi\ lliontwohundredsixtyninethousandtwentyfive": iymr:=vigenere(vpln,[15,17,8,12,4]): ifyo:= "ifyouwanttosolvetheriemannhypothesistrycheckingwikipediaorgoogle firstormaybethatwontwork": spiy:=shift(ifyo,10): scph:= "wnenaydcxoodwcrucxvxaaxffqjcvjhknmxwncqnmjhjocnacxvxaaxfsdbcjbfn uuvjatcfjrw": L100:= [1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0]: L011:= [0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1]: L101:= [1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0]: rsan:= 11438162575788886766923577997614661201021829672124236256256184293 570693\ 5245733897830597123563958705058989075147599290026879543541: rsae:= 9007: rsaci:= 96869613754622061477140922254355882905759991124574319874695120930 81629\ 8225145708356931476622883989628013391990551829945157815154: rsap:= 3490529510847650949147849619903898133417764638493387843990820577: rsaq:= 32769132993266709549961988190834461413177642967992942539798288533 : naive:= 152415787501905985701881832150835089037858868621211004433: cnaive:= 141077461765569500241199505617854673388398574333341423525: n1:=8834884587090814646372459890377418962766907: sigpairm1:= 418726553997094258577980055061305150940547956: sigpairs1:= 749142649641548101520133634736865752883277237: sigpairm2:= 14823765232498712344512418717130930: sigpairs2:= 43176121628465441340112418672065063: signa:= 171024704183616109700818066925197841516671277: signb:= 839073542734369359260871355939062622747633109: sigpb:= 98763457697834568934613: sigqb:=8495789457893457345793: golay:=matrix(12,24,[1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,0,0,0, 1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,1,1,0,0,0,1,0,0,1,0,0,0, 0,0,0,0,0,0,1,1,0,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0, 1,0,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,1,1,0,1,1, 1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0,1,1,1,0,0,0,0,0,0, 1,0,0,0,0,0,1,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,1, 1,0,0,0,1,0,1,1,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,1,0,1, 1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,0,0,1,0,1,1,0,0,0,0,0,0, 0,0,0,0,1,0,1,1,0,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1, 1,1,1,1,1,1,1,1,1,1]): golayb:=matrix(12,12,[1,1,1,0,1,1,1,0,0,0, 1,0,1,0,1,1,0,1,1,1,0,0,0,1,1,1,0,1,1,0,1,1,1,0,0,0,1,0,1,0,1,1, 0,1,1,1,0,0,1,0,0,1,0,1,1,0,1,1,1,0,1,0,0,0,1,0,1,1,0,1,1,1,1,1, 0,0,0,1,0,1,1,0,1,1,1,1,1,0,0,0,1,0,1,1,0,1,1,1,1,1,0,0,0,1,0,1, 1,0,1,0,1,1,1,0,0,0,1,0,1,1,1,1,0,1,1,1,0,0,0,1,0,1,0,1,1,1,1,1, 1,1,1,1,1,1]): hammingpc:=matrix(4,15,[0,0,0,0,1,1,1,1,1,1,1,1,0, 0,0, 1,1,1,0,0,0,0,1,1,1,1,0,1,0,0,0,1,1,1,0,1,1,0,0,1,1,0,0,1,0, 1,0,1,1,1,0,1,0,1,0,1,0,0,0,1]): > XXXX:= "DON'T FORGET TO HIT RETURN TO LOAD THE ABOVE COMMANDS BEFORE STARTING YOUR WORK. PUT THE CURSOR HERE, OR HIGHER, BEFORE HITTING RETURN.": > "spiyegkxddycyvfodrobsowkxxrizydrocscdbimromusxqgsuszonskybqyyqvopsbcdybwkilodrkdg\ (1) yxdgybu" Vector of frequencies of letters appearing in written English (as %). > (2) Vector counting the number of times each letter appears in a given string of text. > (3) Vector of frequencies of letters appearing in a given string of text (as %). (The command evalf() tells Maple to make the calculation as a decimal instead of a fraction.) > (4) > 0.0351704545448400033 Computing the dot product of F with all shifts of 'alfreq': > (5) (6) Find the maximum number on the above list: > 0.06164772725 (7) By inspection we see that this appears in the 11th space, so corresponds to a shift by 10: shifting by -10, we see > "ifyouwanttosolvetheriemannhypothesistrycheckingwikipediaorgooglefirstormaybethatwontwor\ (8) k" Now we try our hand at breaking a Vigenere cipher: > "iymrmgjbrmqfvmgrzvgqqvzuwdemfltjmoscunufdeiogxecyftiqescvbtiiyqdhxjbisiymrsjibtmhkpd\ (9) itkpqjxwbtmhwqhipelesdemmgwzafltjcysukpqxlfxdikzwgwclunigjizhxebtmhnikattizjxelflpk\ btiuznfmtkprmqfvmgrzvgqqvzuwinmxztsqxpxfvrmkvpgrsimpixxpfchzfymacqarinwtycuzqh\ hzffcczvqxwfceecubiickgrmkv" There is a built-in command for encrypting/decrypting a message using a Vigenere cipher. In this (10) example, the key length is 4. It shifts the first letter by 0, the second by 1, the third by 3, the fourth by 19, and then the fifth by 0, the sixth by 1, and so on cycling through the entire message: > "izpkmhmurntyvnjkzwjjqwcnwehffmwcmpvvuoxydflhgyhvygwbqfvvvcwbiztwhymuitlrmsvcic\ (10) wfhlswiuniqkapbupawrkbpfoxsehfmhzsagomjdblulsjxmiqdjnswhzvlvqbgklshyhutnkgildmtj\ ccxfoylqnutjxsngpmkqufqgyfgscogrtozvzbnnastttqpyiornnophulinsbxysycicyyndvqbubnxwr\ cvcjhicyfdfsvrapfdhxcvebidnzrnno" To decrypt our message we need to determine the key length: we check possible key lengths from 1 to 8, > (11) So we suspect that the key length might be 5, and we will try that first (admittedly the evidence is not especially strong, but we find that it works....). The following command picks out every fifth letter of the ciphertext, starting with the first letter: > (12) The following command is a built-in command for calculating the frequency of letters appearing in C1: > (13) > (14) Recall that using a '%' in Maple means that we take as input whatever was the output from the previous line. > 0.06496363638 (15) This appears in the 16th spot, so corresponds to a shift by 15. So we try to decrypt these letters: > "tymrmrjbrmbfvmgczvgqbvzuwoemflejmosnunufoeiogiecyfeiqesnvbtityqdhijbistymrsuibtmskp\ (16) diekpqjiwbtmswqhiaelesoemmghzaflejcysfkpqxwfxdivzwgwnlunirjizhiebtmsnikaetizjielflak\ btifznfmekprmbfvmgczvgqbvzuwtnmxzesqxpifvrmvvpgrdimpiixpfcszfymlcqartnwtynuzqhs\ zffcnzvqxhfceenubiinkgrmvv" Still looks like not much, so we move on to the next set of letters, picking out every 5th letter of the ciphertext, starting with the second letter: > (17) (17) > (18) > (19) > 0.06610909091 (20) This appears in the 18th spot, which we can check by issuing the command: > 0.06610909091 (21) Since the maximum appears in the 18th spot, it corresponds to a shift by 17: > "thmrmrsbrmbovmgcivgqbezuwonmflesmosndnufoniogincyferqesnebtithqdhisbisthmrsurbtmstp\ (22) dietpqjifbtmsfqhianlesonmmghiaflescysftpqxwoxdiviwgwnuunirsizhinbtmswikaecizjinlflatb\ tifinfmetprmbovmgcivgqbezuwtwmxzebqxpiovrmvepgrdrmpiigpfcsifymllqartwwtyndzqhsif\ fcnivqxhoceendbiintgrmve" Still nothing, but we soldier on, looking at every 5th letter starting with the 3rd letter: > (23) > (24) > (25) > 0.06916666667 (26) Max. appears in slot 9, so shift by 8: > "thermrstrmbonmgcingqberuwonefleseosndfufonaoginuyferiesnettithidhististhersurttmsthdiethqj\ (27) ifttmsfihiandesonemghisflesuysfthqxwopdiviogwnumnirsazhinttmswakaecazjindflatttififfme\ thrmbonmgcingqberuwtwexzebixpionrmvehgrdrepiighfcsixymlliartwotyndrqhsixfcninqxhou\ eendtiintyrmve" Hmmm, maybe the first word is 'the'? We keep going: > (28) > (29) > (30) > 0.05629629629 (31) This max appears in the 13th spot, so we shift by 12: > "thefmrstfmbonagcinuqberiwonetlesecsndfifonacginumferissnethithirhistwsthefsurthmsthrietheji\ (32) fthmsfiviandssoneaghistlesumsfthexwopriviouwnumbirsanhinthmswayaecanjindtlatthififtme\ thfmbonagcinuqberiwtwelzebilpionfmvehurdrediightcsixmmlliortwohyndrehsixtcninexhous\ endtwintyfmve" Things are coming into focus a bit more. > (33) > (34) > (35) > 0.06370370371 (36) This max appears in the 5 spot, so corresponding to a shift by 4: Finally, > "thefirstfibonaccinumberisonethesecondfibonaccinumberisonethethirdistwothefourthisthreethefi\ (37) fthisfiveandsooneachisthesumofthetwopreviousnumbersandinthiswaywecanfindthatthefiftiet\ hfibonaccinumberistwelvebillionfivehundredeightysixmilliontwohundredsixtyninethousandt\ wentyfive" Right on! Note that the original message was encrypted by > "iymrmgjbrmqfvmgrzvgqqvzuwdemfltjmoscunufdeiogxecyftiqescvbtiiyqdhxjbisiymrsjibtmhkpd\ (38) itkpqjxwbtmhwqhipelesdemmgwzafltjcysukpqxlfxdikzwgwclunigjizhxebtmhnikattizjxelflpk\ btiuznfmtkprmqfvmgrzvgqqvzuwinmxztsqxpxfvrmkvpgrsimpixxpfchzfymacqarinwtycuzqh\ hzffcczvqxwfceecubiickgrmkv" > (39) "iymrmgjbrmqfvmgrzvgqqvzuwdemfltjmoscunufdeiogxecyftiqescvbtiiyqdhxjbisiymrsjibtmhkpd\ itkpqjxwbtmhwqhipelesdemmgwzafltjcysukpqxlfxdikzwgwclunigjizhxebtmhnikattizjxelflpk\ btiuznfmtkprmqfvmgrzvgqqvzuwinmxztsqxpxfvrmkvpgrsimpixxpfchzfymacqarinwtycuzqh\ hzffcczvqxwfceecubiickgrmkv" So the key is [15,17,8,12,4]. What word does that correspond to? > (39)