單表代替密碼原理及算法實現


    要了解單表替代密碼就得先了解替代密碼,在這里我就做一下簡單的介紹:
      替代是古典密碼中用到的最基本的處理技巧之一 。
      替代密碼是指先建立一個替換表,加密時將需要加密的明文依次通過查表,替換為相應的字符,明文字符被逐個替換后,生成無任何意義的字符串,即密文,替代密碼的密鑰就是其替換表。
      根據密碼算法加解密時使用替換表多少的不同,替代密碼又可分為單表替代密碼和多表替代密碼。
      單表替代密碼的密碼算法加解密時使用一個固定的替換表。單表替代密碼又可分為一般單表替代密碼、移位密碼、仿射密碼、密鑰短語密碼。
      這里講單表替代密碼的直接攻擊。

對於自然語言,如果取一本非專業書籍,統計足夠長的課文就會發現,字母(或字符)出現的頻率會反映出相應語言的統計特性。統計大量的課文定會發現,相應語言中每個字母在相應語言中出現的概率。於是便得到該語言字母表上的一個概率分布。  

一、英文字母

      一由獨立試驗產生明文單碼,Beker在1982年統計的樣本總數為100 362,得到單碼的概率分布見下表:

根據上表,英文字母出現的概率按大小排列如下:

      E T A O I N S H R D L C U M W F G Y P B V K J X Q Z

      在上表中,不少字母出現的概率近乎相等。為了應用方便,常將英文字母表按字母出現的概率大小分類,分類情況見下表:
    
      --------------------------
      極高頻 E
      次高頻 T A O I N S H R
      中等頻 D L
      低頻     C U M W F G Y P B
      甚低頻 V K J X Q Z
      --------------------------
      其它語言和數據也有類似於英語語言的單字母統計特性。如果我們隨意統計一段足夠長的英文課文,只要內容不是太特殊,其結果一定和上表基本相同。這表明英文的一篇文章中各個字母出現的概率是基本可預測的,它將為密碼分析提供一個方面的依據。
      語言的單字母統計特性至少在以下兩個方面沒有反映出英文語言的特征:
      ⑴根據英文的單字母統計特性可以計算出雙字母QE出現的概率為p(QE)=0.00095×0.12702≈1.21×10^(-4)
      這就是說,在10^6個雙字母的抽樣中,QE出現的次數大約應為121次,但這不符合英文課文的實際。因為在英文課文中,QE根本不出現。
      ⑵四字母SEND和SEDN在單字母統計特性下出現的概率相等,這也不符合英文的實際。總之,自然語言的單字母統計特性只反映了單字母出現的概率,而沒有反映該種語言文字的字母間的相關關系。為了體現自然語言的雙字母統計特性,我們需要考察該語言的文字中相鄰字母對出現的頻數。

二、由獨立試驗產生雙字母。根據Beker在1982年統計的英文雙字母的頻數給出了雙字母的頻率。

      統計出的英文雙字母的概率最大的30對字母按概率大小排列為:

th    he    in    er    an    re    ed    on    es    st    en    at    to    nt    ha    nd    ou    ea    ng    as    or    ti    is    et    it    ar    te     se    hi    of  
      只要我們隨意統計足夠長的英文課文,只要內容不是太特殊,其結果一定和上面的概率基本相同,這也表明雙字母在英文課文中出現的概率是基本可預測的,它為密碼分析提供了又一方面的依據。

      類似的,我們還可以考察英文課文中三字母出現的頻率。仍按Beker在1982年統計的結果(樣本總數100 360)得到概率最大的20組三字母按概率大小排列為:

the    ing    and    her    ere    ent    tha    nth    was    eth    for    dth    hat    she    ion    his    sth    ers    ver  
      特別,the出現的頻率幾乎為ing的3倍。
      應當強調指出,在利用統計分析法時,密文量要足夠大,否則會加大密碼攻擊的難度。在實際通信中,除了字母外,還有諸如標點、數字等字符,它們的統計特性也必須考慮進去。數據格式、報頭信息對於密碼體制的安全有重要意義,在密碼分析中也起着重要的作用。
      在分析或攻擊一份密報時利用英文的下述統計特性很有幫助。
      ⑴冠詞the對英文的統計特性影響很大,它使t,h,th,he和the在單字母、雙字母和三字母的統計中都為高概率的元素。
      ⑵英文單詞中以 E,S,D,T 為結尾的超過一半
      ⑶英文單詞中以 T,A,S,W 為起始字母的約占一半
      ⑷①在分析或攻擊密文時應先找突破口,一般來說,先從the a i入手。(能一個字母獨立作為單詞的只有a、I,而且頻率較高時優先考慮a)
      ②如果有“’”出現,“’”后的一個字母只能是t s l d v中的一個;如果是兩個字母,則只能是re ll。(兩個不同字母即是re,相同即是ll)
      ③其它規律:如果四字單詞詞末有兩個相同字母,往往是ll;
      以a開頭的三字單詞只能是and are中的一個;
      兩個字母的組合中如果出現q*,則*是u(q后幾乎總是u);
      如果一個單詞的開頭和結尾是同一個字母,最可能的是:s t d;
      兩個都是輔音的雙字母組合,常含有n或t;io、ou和ea是最常見的雙元音字母組;
      如果單詞的頭兩個字母都是輔音,則第二個字母最可能是:r、l和h;
      如果一個三次以三個輔音結尾,那最常見的是-ght和-tch;
      反向雙字母組合: er-re, es-se, an-na, it-ti, on-no, en-ne, ot-to,ed-de, st-ts, at-ta, ar-ra, in-ni;

      小詞的使用頻率
      1-letter: a,i,o
      2-letter: of,to,in,is,it,be,as,at
      3-letter: the,and,for,are,but,not,you,all
      4-letter: that,with,have,this,will,your,from,they
      5-letter: which,would,there

      元音字母:a,e,i,o,u
      元音后最常見的字母是n,元音前最常見的字母是h

      常見的雙字母前綴 re co un com il ir up
      最常用的三字母后綴 ion ing
      最常見詞尾 ed es er
【例】
      1.攻擊例題:
      給定密文為GROX CMRYYVLYIC COXN COMBOD WOCCKQOC DY OKMR YDROB DROI YPDOX SXFOXD K MYNO LI VODDSXQ OKMR VODDOB YP DRO KVZRKLOB BOZBOCOXD KXYDROB YXO

      攻擊的第一步是做出密文字母出現的頻次分布表

第二步是根據密文字母的頻次統計,確定某些密文字母對應的明文字母可能是單字母頻率統計表中的哪些字母。此例中
      密文字母           對應的明文字母
      O,D,B,V                e,t,r,l
      第三步是利用自然語言的文字結合規律進行猜測。D經常出現在詞頭或詞尾,故猜測它與t對應;而P經常在詞尾出現而未在詞頭出現,所以猜測它與明文字母e對應;K單獨出現且頻率較高,猜測與a對應。
      利用雙字母、三字母統計特性及元音輔音拼寫知識,可猜測如下:

由此不難猜出:GROX是when,OKMR是each,VODDSXQ是letting,KXYDROB是another,DY是to。
      再得到下表:

再做進一步確定就可確定C,W,I,N,F,Q,Z對應的明文字母。經過整理恢復的明文如下:
when schoolboys send secret messages to each other they often invent a code by letting each letter of the alphaber represent another one.

算法實現

 1 #include <iostream>
 2 #include <fstream>
 3 #include <cstdlib>
 4 using namespace std;
 5 const char c[27]={'d','j','k','z','u',
 6                 'x','c','m','l','i','w','b','v','n','o','p',
 7                 'q','a','r','s','g','h',
 8                 'f','t','y','e',' '};
 9 void encryption(ifstream& fin,ofstream& fout);
10 int main()
11 {
12     ifstream fin;
13     ofstream fout;
14     fin.open("file1_1.in");
15     if(fin.fail())
16     {
17         cout<<"File open error!(Input)"<<endl;
18         exit(1);
19     }
20     fout.open("file1_1.out");
21     if(fout.fail())
22     {
23         cout<<"File open error!(Output)"<<endl;
24     }
25     encryption(fin,fout);
26     fin.close();
27     fout.close();
28     return 0;
29 }
30 void encryption(ifstream& fin,ofstream& fout)//加密過程
31 {
32     char next;
33     char ch;
34     int i;
35     while(fin.get(next))
36     {
37         if(next>='a'&&next<='z')
38         {
39             i=next-'a';
40             ch=c[i];
41             fout<<ch;
42         }
43         else
44         {
45             fout<<' ';
46         }
47     }
48 }
49 void decryption(ifstream& fin,ofstream& fout)//解密過程
50 {
51     char ch;
52     char chout;
53     while(fin.get(ch))
54     {
55         for(int i=0;i<=26;i++)
56         {
57             if(ch==c[i])
58             {
59                 if(i==26)
60                 {
61                     fout<<' ';
62                 }
63                 else
64                 {
65                     chout=char('a'+i);
66                     fout<<chout;
67                 }
68             }
69         }
70     }
71 }

輸入文件file1_1.in

//file1_1.in
we will attack tomorrow morning

輸出文件file1_1.out

//file1_1.out
fu flbb dssdkw sovoaaof voanlnc

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM