第三章古典密碼之旅(上)

pages 47 - 77

位移密碼

abc = "abcdefghijklmnopqrstuvwxyz";
cap = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
shiftencryptkey[n_] := 
        Table[StringTake[abc, {i}] -> 
            StringTake[cap, {Mod[i - 1 + n, 26] + 1}], {i, 1, 
            26}];
shiftencrypt[plaintext_, n_] := 
        StringReplace[plaintext, shiftencryptkey[n]];
shiftdecryptkey[n_] := 
        Table[StringTake[cap, {i}] -> 
            StringTake[abc, {Mod[i - 1 + n, 26] + 1}], {i, 1, 
            26}];
shiftdecrypt[plaintext_, n_] := 
        StringReplace[plaintext, shiftdecryptkey[n]];
shiftdecryptall[txt_] := 
        Do[Print[shiftdecrypt[txt, n]], {n, 26}];
ga = "gaulisdividedintothreeparts";
yc = "YCVEJQWVHQTDTWVWU";

例題01 用位移密碼 k=3 來加密 gaul is divided into three parts。

cryptga = shiftencrypt[ga, 3]

shiftdecrypt[%, -3]

例題02 經位移密碼加密為 YCVEJGWVHQTDTWVWU, 試解密之。

shiftdecryptall[yc]

例題03 用仿射函數 7x+8 來加密 i love you very much。

abc = "abcdefghijklmnopqrstuvwxyz";
cap = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    affencryptkey[m_, n_] := 
      Table[StringTake[abc, {i}] -> 
          StringTake[cap, {Mod[m*(i - 1) + n, 26] + 1}], {i, 
          26}];
affencrypt[plaintext_, m_, n_] := 
        StringReplace[plaintext, affencryptkey[m, n]];
affdecryptkey[m_, n_] := 
        Table[StringTake[cap, {i}] -> 
            StringTake[abc, {Mod[m*(i - 1) + n, 26] + 1}], {i, 
            26}];
affdecrypt[plaintext_, m_, n_] := 
        StringReplace[plaintext, affdecryptkey[m, n]];
ed = "EDSGICKXHUKLZVEQZVKXWKZUKCVUH";
tc = "TCABTIQMFHEQQMRMVMTMAQ";

affencrypt["iloveyouverymuch", 7, 8]

affdecrypt["MHCZKUCSZKXUOSWF", 15, 10]

例題04 用仿射函數 5x+12 加密，其密文為 MZDVEZC。試解密之。

PolynomialMod[PowerMod[5, -1, 26] (y - 12), 26]

Solve[{y == 5*x + 12, Modulus == 26}, x, 
      Mode -> Modular]

affdecrypt["MZDVEZC", 21, 8]

維吉內爾密碼

abc = "abcdefghijklmnopqrstuvwxyz";
cap = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    vigencryptkey[m_, n_] := 
      Table[StringTake[abc, {i}] -> 
          StringTake[
            cap, {Mod[i - 1 + m[[Mod[n - 1, Length[m]] + 1]], 26] + 
                1}], {i, 1, 26}];
vigencrypt[plaintext_, v_] := 
        StringJoin[
          Module[{z}, z = {}; 
            Do[z = Insert[z, 
                  StringReplace[Characters[plaintext][[i]], 
                    vigencryptkey[v, Mod[i - 1, Length[v]] + 1]], i], {i, 
                StringLength[plaintext]}]; z]];
vigdecryptkey[m_, n_] := 
        Table[StringTake[cap, {i}] -> 
            StringTake[
              abc, {Mod[i - 1 + m[[Mod[n - 1, Length[m]] + 1]], 26] + 
                  1}], {i, 1, 26}];
vigdecrypt[plaintext_, v_] := 
        StringJoin[
          Module[{z}, z = {}; 
            Do[z = Insert[z, 
                  StringReplace[Characters[plaintext][[i]], 
                    vigdecryptkey[v, Mod[i - 1, Length[v]] + 1]], i], {i, 
                StringLength[plaintext]}]; z]];

abc = "abcdefghijklmnopqrstuvwxyz";
\(\(num = "0001020304050607080910111213141516171819202122232425";\)\)
digitalize = 
        Table[StringTake[abc, {i}] -> 
            StringTake[num, {2*i - 1, 2*i}], {i, 1, 26}];
alphabetize = 
        Table[StringTake[num, {2*i - 1, 2*i}] -> 
            StringTake[abc, {i}], {i, 1, 26}];
Q0[plaintext_] := StringReplace[plaintext, digitalize];

tunghai = 
      Table[StringTake[Q0["tunghai"], {i, i + 1}], {i, 1, 14, 2}] // 
        ToExpression

vigencrypt["iloveyouverymuch", tunghai]

vigdecrypt[%, -tunghai]

頻率分析 yih

cap = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    frequency[txt_] := 
      Array[Function[
          i, {Characters[cap][[i]], 
            Count[Characters[txt], Characters[cap][[i]]]}], 
        26];

\(\(yih = "YIHXZCWKYNTKSMOYAELAZLUTUVUZYUGNLRAULBANHBYIEZOOVMBVYJOVMCAKUTIGYJTHTQHHPUUCMBPRJPNTBVRXAYIGXQKKIKTNRJAOBAYCXVPWLCGOVNBAUGGSLUXHNXLCZXUGKKEYNUYTVWEXUEKLNOTARJPNIZLRGACQOCYCHRBXMGOUGEAYGNLRBAUGTHTQHHBXHNGGUGOVNAHWBTJEQOYQGUDAHXRJPCIMYQIHNTHHTKUDCKYJKHRMFYGUUAOKYNZIABMFRLPETWISZOABPUECLHIOYPUTEBHXRJPCIMYNVVRBBIAUMTPTNSOLLLTMNLPNIELRYAIVZJYGJENHLGNVSMPBBNLRMZUIKAHMBLYOCEAMBNZAHIMHNZPOVFCTNALQOYVZPSIENBMLTPXLSOATQGANTKPZHJRXAHIMQRYOOCEXQUAHQLVHZPNIEUEMLRAXHFKDEKTHAUADMWCPGAEEXWNTUOBVIAYLCZTNRCLCIGHBZOATEIJZOIAZLBAUDBAYOXHVMFYARPVQGANTKDMTXJNVSBKOTMSELAYEKOADXWBTZEKKUGKKIBYUEGIODXIHXWOWKJBCLRBHUQJVRLXNEGJTBAYJUYLLPCYRSIBMFRTVTMGIERVNOKYZKTBMKQUGAWMLULNLRMUOGOACIGHRBLRNHLTKAWPTNGNLYLBXUKYEQMCFLVRCLNUKSIDBHTXHTPXLGUIELXXVIHTMWBRXLTWMBRAUFQGCFNLDEHLXCOIKANUKFWPHZBANHBAYEKOADXNUAZFIKMBTVBTRUQBHNKXXVZPSZTNUKYFWKOFZVBMAYEKKELBWNZLDBHNUKNRMTNGGZKZXGNOUIVZVRLVRMNMGNHTNKIZZOEAXBBTVRMWXRGKWMMUXKPNKKYNYLDLXPBZPOVMIGNHTKTOFKMOZPBVIOTPXSTGCEBAYYGZTNNFYSLAANLRUMDMOIGOVNBAUGCLHMKYUONHTRLRYVLDXNUGATPXMRJLALLBNRSNWMBNBLDQXXVTCAQGNUGATPBMAGAIWGOAJLROHXFNHLTAUIKHNMPVVXAHWYZEKLDWFUAJAHIMABBLRVFYAZVFBAYCKVPTXVLZOEXXICRLFWKNUKWEWIFRYOATEHBZWEZBMULYOUMBRKHRBA      ";\)\)

frequency[yih]

Table[{j, 
        Count[Table[
            If[StringTake[yih, {i}] == StringTake[yih, {i + j}], 
              t, {}], {i, 1, 1149 - j}], t]}, {j, 8}]

choose[txt_, m_, n_] := 
        StringJoin[
          Module[{z}, 
            z = {}; 
Do[
              z = Insert[z, StringTake[txt, {m*(i - 1) + n}], i], {i, 1, 
                Floor[StringLength[txt]/m]}]; z]];

frequency[choose[yih, 7, 1]]

frequency[choose[yih, 7, 2]]

frequency[choose[yih, 7, 3]]

frequency[choose[yih, 7, 4]]

frequency[choose[yih, 7, 5]]

frequency[choose[yih, 7, 6]]

frequency[choose[yih, 7, 7]]

vigdecrypt[yih, -{19, 20, 13, 6, 7, 0, 8}]

v1 = 
      Table[frequency[choose[yih, 7, 1]][[i]][[2]], {i, 1, 
          26}]

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};
s[a_, b_, n_] := 
        Sum[a[[i]]*b[[Mod[i - n - 1, 26] + 1]], {i, 26}];
corr[a_] := Table[s[a, alfreq, i], {i, 0, 25}];

corr[v1]

v2 = 
      Table[frequency[choose[yih, 7, 2]][[i]][[2]], {i, 1, 
          26}]

corr[v2]

v3 = 
      Table[frequency[choose[yih, 7, 3]][[i]][[2]], {i, 1, 
          26}]

corr[v3]

v4 = 
      Table[frequency[choose[yih, 7, 4]][[i]][[2]], {i, 1, 
          26}]

corr[v4]

v5 = 
      Table[frequency[choose[yih, 7, 5]][[i]][[2]], {i, 1, 
          26}]

corr[v5]

v6 = 
      Table[frequency[choose[yih, 7, 6]][[i]][[2]], {i, 1, 
          26}]

corr[v6]

v7 = 
      Table[frequency[choose[yih, 7, 7]][[i]][[2]], {i, 1, 
          26}]

corr[v7]

v[j_] := 
        Table[frequency[choose[yih, 7, j]][[i]][[2]], {i, 1, 
            26}];
tunghai = 
      Table[Position[corr[v[j]], 
                Max[corr[v[j]]]][[1]][[1]], {j, 1, 7}] - 
        1