restart; with(Maplets[Elements]): strgraph := proc(sl) local i, j, k, str1, ctl, str2, strset, flist, mess, dl, pset: global ct, pun; pset := {seq(StringTools:-Char(i), i = 32..47), seq(StringTools:-Char(i), i = 58..64), seq(StringTools:-Char(i), i = 91..96), seq(StringTools:-Char(i), i = 123..127)}; if sl = 1 then dl := 1; else dl := 2; fi: strset := {}: flist := []: mess := ct; for i from 1 to length(mess)-sl+1 do ctl := 1: str1 := substring(mess, i..i+sl-1): if pun = "true" then if not member(str1, strset) and not member(str1, pset) 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 ctl := ctl + 1: fi: od: fi: else if not member(str1, strset) then for j from i+sl to length(mess)-sl+1 do str2 := substring(mess, j..j+sl-1): if str1=str2 then ctl := ctl + 1: fi: od: fi: fi: if ctl >= dl and not member(str1, strset) then if pun = "true" then if not member(str1, pset) then flist := [op(flist), [cat(convert(sl, string), " graph ",str1, " occurs ", convert(ctl, string)," times"), ctl]]; fi: else flist := [op(flist), [cat(convert(sl, string), " graph ",str1, " occurs ", convert(ctl, string)," times"), ctl]]; fi: fi: strset := strset union {str1}: od: flist := sort(flist, (x,y) -> evalb(x[2] > y[2])); if nops(flist) = 0 then cat("No common ", convert(sl, string), " graphs were found."); else seq([convert(flist[i][1], symbol)], i = 1..nops(flist)); seq(flist[i][1], i = 1..nops(flist)); fi: end: doublelet := proc() local i, flist, d, dct, lb, ub; global ct, pun; flist := []; if pun = "true" then lb := 65; ub := 90; else lb := 32; ub := 127; fi: for i from lb to ub do d := cat(StringTools:-Char(i),StringTools:-Char(i)); dct := nops([StringTools:-SearchAll(d, ct)]); if dct > 0 then flist := [op(flist), [cat("Double letter sequence ", d, " occurs ", convert(dct, string), " times"), dct]]; fi: od: flist := sort(flist, (x,y) -> evalb(x[2] > y[2])); if nops(flist) = 0 then "No doubles were found."; else seq(flist[i][1], i = 1..nops(flist)); fi: end: reversal := proc() local i, flist, r, strset; global ct, pun; flist := []; strset := {}; for i from 1 to length(ct)-1 do r := 0; if not member(cat(ct[i], ct[i+1]), strset) and cat(ct[i], ct[i+1]) <> cat(ct[i+1], ct[i]) then if pun = "true" then if StringTools:-IsAlpha(ct[i]) and StringTools:-IsAlpha(ct[i+1]) then r := StringTools:-Search(cat(ct[i+1], ct[i]), ct); fi: else r := StringTools:-Search(cat(ct[i+1], ct[i]), ct); fi: if r > 0 then flist := [op(flist), [cat("Reverse sequence ", cat(ct[i], ct[i+1]), "/", cat(ct[i+1], ct[i]), " occurs in ciphertext")]]; strset := strset union {cat(ct[i], ct[i+1]), cat(ct[i+1], ct[i])}: fi: fi: od: if nops(flist) = 0 then "No reversals were found."; else seq(flist[i][1], i = 1..nops(flist)); fi: end: bword := proc(ct, bl) local i, t, b, nct; t := StringTools:-Split(ct, " "); b := ""; nct := ""; i := 1; while i <= nops(t) do b := t[i]; while length(b) < bl and i <> nops(t) do if length(b) + 1 + length(t[i+1]) <= bl then i := i + 1; b := cat(b, " ", t[i]); else b := cat(b, StringTools:-Fill(" ", bl - length(b))); fi: od: nct := cat(nct, b); i := i + 1; od: nct; end: csetup1 := proc(ctext, ic) local pc, fpc, i, j; global q, r, pt, ct, pun, vis; pun := ic; if ic = "true" then ct := bword(StringTools:-Select(StringTools:-IsPrintable, StringTools:-UpperCase(ctext)), 16); else ct := StringTools:-Select(StringTools:-IsPrintable, StringTools:-UpperCase(ctext)); fi: pt := StringTools:-Fill(" ", length(ct)); if ic = "true" then pc := "!#$%&'()*+,-./:;<=>?@[\]^_`{|}~ "; for i from 1 to length(pc) do fpc := [StringTools:-SearchAll(pc[i], ct)]; for j from 1 to nops(fpc) do pt := StringTools:-Insert(pt, fpc[j], pc[i]); pt := StringTools:-Delete(pt, fpc[j]..fpc[j]); od: od: fi: q := iquo(length(ct), 16, 'r'); if r = 0 then vis := 'false'; else vis := 'true'; fi: end: csetup2 := proc() local i, j, k; global q, r, pt, ct, pun; k := 0; for i from 1 to q do for j from 1 to 16 do k := k + 1; Maplets:-Tools:-Set(cat("CT", convert((i-1)*16+j, string))('caption') = ct[k], cat("PT", convert((i-1)*16+j, string))('value') = pt[k]); if (StringTools:-IsPunctuation(ct[k]) = true or ct[k] = " ") and pun = "true" then Maplets:-Tools:-Set(cat("CT", convert((i-1)*16+j, string))('enabled') = 'false', cat("PT", convert((i-1)*16+j, string))('editable') = 'false'); fi: od: od: for j from 1 to r do k := k + 1; Maplets:-Tools:-Set(cat("CT", convert(q*16+j, string))('enabled') = 'true', cat("PT", convert(q*16+j, string))('enabled') = 'true'); Maplets:-Tools:-Set(cat("CT", convert(q*16+j, string))('background') = 'white', cat("PT", convert(q*16+j, string))('background') = 'white'); Maplets:-Tools:-Set(cat("CT", convert(q*16+j, string))('caption') = ct[k], cat("PT", convert(q*16+j, string))('value') = pt[k]); if (StringTools:-IsPunctuation(ct[k]) = true or ct[k] = " ") and pun = "true" then Maplets:-Tools:-Set(cat("CT", convert(q*16+j, string))('enabled') = 'false', cat("PT", convert(q*16+j, string))('editable') = 'false'); fi: od: end: fgraphp := proc(tl) global tlc; tlc := tl; end: actext := proc(lnum) local i, glet; global ct, lloc; for i from 1 to nops(lloc) do Maplets:-Tools:-Set(cat("CT", convert(lloc[i], string))('foreground') = 'red') od: glet := ct[lnum]; lloc := [StringTools:-SearchAll(glet, ct)]; for i from 1 to nops(lloc) do Maplets:-Tools:-Set(cat("CT", convert(lloc[i], string))('foreground') = 'black') od: end: aptext := proc(let) local i, elet; global ct, lloc; if nops(lloc) > 0 then elet := Maplets:-Tools:-Get(cat("PT", convert(lloc[1], string))); if elet <> " " then Maplets:-Tools:-Set(convert(cat("PT", elet), symbol)('foreground') = 'blue'); Maplets:-Tools:-Set(convert(cat("PT", elet), symbol)('enabled') = 'true'); fi: if convert(let, string) <> "DEL" then Maplets:-Tools:-Set(convert(cat("PT", convert(let, string)), symbol)('foreground') = 'black'); Maplets:-Tools:-Set(convert(cat("PT", convert(let, string)), symbol)('enabled') = 'false'); for i from 1 to nops(lloc) do Maplets:-Tools:-Set(cat("PT", convert(lloc[i], string))('value') = convert(let,string)); od: else for i from 1 to nops(lloc) do Maplets:-Tools:-Set(cat("PT", convert(lloc[i], string))('value') = " "); od: fi: fi: end: dptext := proc() local i, j, k, ptv, cpt, n, pts; global q, r, pt, ct, pun; n := length(pt); cpt := Array(1..n); for k from 1 to n do if pt[k] = " " and ct[k] <> " " and pun = "true" then cpt[k] := "*"; else cpt[k] := pt[k]; fi: od: k := 0; for i from 1 to q do for j from 1 to 16 do k := k + 1; ptv := Maplets:-Tools:-Get(cat("PT", convert((i-1)*16+j, string))); if ptv <> " " and pun = "true" then cpt[k] := ptv; elif pun = "false" then cpt[k] := ptv; fi: od: od: for j from 1 to r do k := k + 1; ptv := Maplets:-Tools:-Get(cat("PT", convert(q*16+j, string))); if ptv <> " " and pun = "true" then cpt[k] := ptv; elif pun = "false" then cpt[k] := ptv; fi: od: pt := ""; pts := ""; for k from 1 to n do pt := cat(pt, cpt[k]); pts := cat(pts, cpt[k]); if irem(k, 16) = 0 and pun = "true" and length(StringTools:-Remove(StringTools:-IsSpace, substring(pt, k-15..k))) < 16 then pts := cat(pts, " "); fi: od: if pun = "true" then convert(StringTools:-Join(remove(type,StringTools:-Split(pts),""), " "), symbol); else convert(pt, symbol); fi: end: fsetup := proc(ftype) local res; global tlc; if ftype = "single letter" then Maplets:-Tools:-Set('TB2' = [strgraph(1)]); elif ftype = "digraph" then Maplets:-Tools:-Set('TB2' = [strgraph(2)]); elif ftype = "trigraph" then Maplets:-Tools:-Set('TB2' = [strgraph(3)]); elif ftype = "other text length" then Maplets:-Display(fgraph); Maplets:-Tools:-Set('TB2' = [strgraph(tlc)]); elif ftype = "double" then Maplets:-Tools:-Set('TB2' = [doublelet()]); elif ftype = "reversals" then Maplets:-Tools:-Set('TB2' = [reversal()]); fi: end: fin := "false": kgoing := "false": while fin = "false" do lloc := []: subsetup := Maplet('onstartup' = 'A1', Window['W1']( 'title'="Substitution Cipher Breaker", BoxColumn('halign' = 'none', 'background' = 'navy', BoxRow('halign' = 'none', "Ciphertext: ", TextBox['TB1']('font' = Font("arial", bold, 12), 'foreground' = 'red', 9..50), seq(HorizontalGlue(), i = 1..10)), BoxRow('halign' = 'none', "Include all characters (including non-letters) in frequency counts? ", RadioButton['RB1']("Yes", 'value'=false, 'group'='BG1'), RadioButton['RB2']("No", 'value'=true, 'group'='BG1'), Button("What is this?", RunDialog('MRB'))), BoxRow('halign' = 'none', Button("Cryptanalyze Message", Action(Evaluate('function' = "csetup1", Argument('TB1', 'quotedtext' = 'true'), Argument('RB2', 'quotedtext' = 'true')), Shutdown("true"))) ) ) ), Action['A1'](RunWindow('W1')), ButtonGroup['BG1'](), MessageDialog['MRB']("If no is selected, only letters in the ciphertext will be considered when calculating frequencies. If yes is selected, all characters, including numbers and punctuation characters, will be considered in the frequency counts", 'type' = 'information') ): kgoing := Maplets[Display]( subsetup ): if kgoing = "true" then sbreaker := Maplet('onstartup' = 'A1', Window['W1']('title' = "Substitution Cipher Cryptanalysis", BoxColumn('halign' = 'none', BoxRow('halign' = 'none', spacing = 1, inset = 1, BoxColumn('valign' = 'none', seq(VerticalGlue(), i = 1..5), spacing = 1, inset = 1, DropDownBox['DDB1']( 'value' = "?", ["?", "single letter","digraph", "trigraph", "other text length", "double", "reversals"], 'width' = 85, onchange = Action(Evaluate('function' = "fsetup", Argument('DDB1', 'quotedtext' = 'true'))) ), "Select frequency type", seq(VerticalGlue(), i = 1..5)) ,TextBox['TB2']( 'editable' = 'false', 'font' = Font("arial", bold, 12), 7..55 ), seq(HorizontalGlue(), i = 1..10) ), BoxRow('halign' = 'center', 'background' = 'navy', Button("Display current plaintext", Action(Evaluate('TDPT' = 'dptext()'), RunWindow('W2'))), Button( "Decipher another message", Shutdown("false")), Button("Quit", Shutdown("true") ), Button("How does the Maplet work?", RunDialog('MMW'))), BoxRow('halign' = 'none', seq(HorizontalGlue(), i = 1..5), spacing = 1, inset = 1, 'border' = 'true', 'font' = Font("times", bold, 14), 'caption'= " Plaintext Alphabet ", BoxColumn('halign' = 'none', spacing = 1, inset = 1, BoxRow('halign' = 'none', Button['PTA']('foreground' = 'blue', 'caption' = "A", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(A)')), Button['PTB']('foreground' = 'blue', 'caption' = "B", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(B)')), Button['PTC']('foreground' = 'blue', 'caption' = "C", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(C)')), Button['PTD']('foreground' = 'blue', 'caption' = "D", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(D)')),Button['PTE']('foreground' = 'blue', 'caption' = "E", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(E)')),Button['PTF']('foreground' = 'blue', 'caption' = "F", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(F)')),Button['PTG']('foreground' = 'blue', 'caption' = "G", 'width' = 43, 'font' = Font("times", bold,12), Evaluate('function' = 'aptext(G)')),Button['PTH']('foreground' = 'blue', 'caption' = "H", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(H)')),Button['PTI']('foreground' = 'blue', 'caption' = "I", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(I)')),Button['PTJ']('foreground' = 'blue', 'caption' = "J", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(J)')),Button['PTK']('foreground' = 'blue', 'caption' = "K", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(K)')),Button['PTL']('foreground' = 'blue', 'caption' = "L", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(L)')),Button['PTM']('foreground' = 'blue','caption' = "M", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(M)'))), BoxRow('halign' = 'none', Button['PTN']('foreground' = 'blue', 'caption' = "N", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(N)')),Button['PTO']('foreground' = 'blue', 'caption' = "O", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(O)')),Button['PTP']('foreground' = 'blue', 'caption' = "P", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(P)')),Button['PTQ']('foreground' = 'blue', 'caption' = "Q", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(Q)')),Button['PTR']('foreground' = 'blue', 'caption' = "R", 'width' = '43', 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(R)')),Button['PTS']('foreground' = 'blue', 'caption' = "S", 'width' = '43', 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(S)')),Button['PTT']('foreground' = 'blue', 'caption' = "T", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(T)')),Button['PTU']('foreground' = 'blue', 'caption' = "U", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(U)')),Button['PTV']('foreground' = 'blue', 'caption' = "V", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(V)')),Button['PTW']('foreground' = 'blue', 'caption' = "W", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(W)')),Button['PTX']('foreground' = 'blue', 'caption' = "X", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(X)')),Button['PTY']('foreground' = 'blue', 'caption' = "Y", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(Y)')),Button['PTZ']('foreground' = 'blue', 'caption' = "Z", 'width' = 43, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(Z)')))), Button['PTDEL']('foreground' = 'blue', 'caption' = "DEL", 'width' = 55, 'font' = Font("times", bold, 12), Evaluate('function' = 'aptext(DEL)')), seq(HorizontalGlue(), i = 1..5)), BoxColumn('halign' = 'none', 'valign' = 'none', 'vscroll' = 'as_needed', spacing = 1, inset = 1, 'border' = 'true', 'font' = Font("times", bold, 14), 'caption'= " Plaintext/Ciphertext Match ", seq(BoxColumn('halign' = 'none', spacing = 1, inset = 1, border = true, BoxRow('halign' = 'none', spacing = 1, inset = 1, "Plain: ", seq(TextField[cat("PT", convert((i-1)*16+j, string))]('halign' = 'center', 'width' = 2, 'font' = Font("times", bold, 11), 'foreground' = 'blue', 'background' = 'white'), j = 1..16)), BoxRow('halign' = 'none', spacing = 1, inset = 1, "Cipher:", seq(Button[cat("CT", convert((i-1)*16+j, string))]('width' = 44, 'caption' = " ", 'font' = Font("times", bold, 11), 'foreground' = 'red', 'background' = 'white', Action(Evaluate('TS' = (i-1)*16+j), Evaluate('function' = 'actext(TS)'))), j = 1..16))), i = 1..q), BoxRow(TextField['TS'](10), 'visible' = 'false'), BoxColumn('halign' = 'none', spacing = 1, inset = 1, border = true, 'visible' = vis, BoxRow('halign' = 'none', inset = 1, spacing = 1, "Plain: ", seq(TextField[cat("PT", convert(q*16+j, string))]('halign' = 'center', 'width' = 2, 'enabled' = 'false', 'font' = Font("times", bold, 11), 'foreground' = 'blue', 'background' = 'black'), j = 1..16)), BoxRow('halign' = 'none', inset = 2, spacing = 1, "Cipher:", seq(Button[cat("CT", convert(q*16+j, string))]('width' = 44, 'caption' = " ", 'enabled' = 'false', 'font' = Font("times", bold, 11), 'foreground' = 'red', 'background' = 'black', Action(Evaluate('TS' = q*16+j), Evaluate('function' = 'actext(TS)'))), j = 1..16)) ) ) )), Window['W2']( 'title'="Plaintext Viewer", BoxColumn('halign' = 'none', 'background' = 'navy', BoxRow('halign' = 'none', "Plaintext: ", TextBox['TDPT']('font' = Font("arial", bold, 12), 'foreground' = 'blue', 9..50), seq(HorizontalGlue(), i = 1..10)), BoxRow('halign' = 'none', Button("Go Back", CloseWindow('W2')) ) ) ), MessageDialog['MMW']("Using calculated frequencies of the ciphertext given above, the user can cryptanalyze the message by selecting ciphertext letters and clicking on matching plaintext messages in the plaintext alphabet until the message is spelled out." , 'type' = 'information'), Action['A1'](RunWindow('W1'), Evaluate('function' = 'csetup2()')) ): fgraph := Maplet( Window['W1']( BoxColumn('halign' = 'none', BoxRow('halign' = 'none', "Enter length of text string for frequency analysis", TextField['GL']('font' = Font("arial", bold, 12), 3)), BoxRow('halign' = 'none', Button("Go Back to Substitution Cryptanalyis Window", Action(Evaluate('function' = 'fgraphp(GL)'), CloseWindow('W1')))) )) ): fin := Maplets[Display]( sbreaker ): else fin := "true" fi: od: # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #