單字母密碼密碼分析(下)

上一篇我們分析了單表替換破譯的思路,下面看看具體的實現過程吧~

2. 算法細節

2.1 一、二元詞試探

這個方法基於一個假設:明文中的一元詞和二元詞都會出現在S,D集合中,如果出現了不在集合中的單詞,後面我們會做一步篩選來排除這些干擾。在這樣的前提下,我們用試探的方式逐一匹配S,D集合中的詞。

            例如密文    di sygq t uspe tzsi ventzew sb st

我們找出密文中一元二元詞{s, t}、{sb,st},就可以假設有密鑰{s-a, t-i}、{sb-of, st-to},而sb-of可以得出{s-o, b-f},st-to可以得出{s-t,t-o}。將映射關係存入解碼字母表中,我們就會發現字母表存在衝突,即一元詞已經得出了{s-a},{t-i}這兩個映射關係,後面又出現了{s-t},{t-o}。

    這時就要作一步取捨,假設一元詞的映射關係是正確的,放棄當前二元詞找到的映射關係。繼續在集合D中匹配下一個單詞。這樣的匹配關係記錄下來就是一張表格的形式,例如表1.1

表1.1

C\P

of

to

in

it

nb




vn




wv





    假設{w-i}放到解碼字母表時產生衝突,那麼{wv-in}的對應關係就要更改,以單詞頻率的先後順序方式查找的話,下一個可能性應該是明文單詞it,此時的對應關係表見表1.2

表1.2

C\P

of

to

in

it

nb




vn




wv





    如果密文wv在遍歷了所有的二元詞都產生衝突情況下,這時我們就要考慮之前的試探配對是不是出錯了,基於我們假設的前提是篩選後的二元詞都會出現在集合D中的,所以這時要選擇放棄前一個映射關係,這裏就是{bd-to},在解碼字母表中去除{b-t}及{d-o}的編碼。這時再讓密文wv重新查找是否存在合適的明文與之匹配。表1.3是最後的匹配結果,找到了所有詞的合適的映射,這樣的過程類似於回溯執行,是一種試探的方法。

表1.3

C\P

of

to

in

it

no

nb





vn





wn






    當二元單詞都找不到合適的對應關係時,這就說明是上一部分的假設出錯了,即一開始設想的一元詞對應關係是不正確的,現在要返回去修改。一元詞密文與明文之間的對應關係如表1.4所示,類似於前面的做法,密文與明文的映射關係可以用vector或是array來保存,回溯時修改裏面的數值即可。但不同的是一元詞沒修改一次,就繼續往下回到二元詞表中進行回溯,如果依舊衝突,則再返回一元表修改其中的映射關係。如此往復進行後,由於S,D集合十分小,這種情況我們很快就可以破解出這些詞的明文形式。

表1.4

C\P

i

a

s

m

k




v




e




    

  儘管上面破譯出來的字母可以通過篩選密文中二元詞頻率的方式來排除異常詞的干擾,如 



2.2 三元詞分析

根據參考資料,三元詞也同樣具備明顯的頻率特徵,比如句子中常見的關係代詞,介詞,謂語動詞等等中有很大一部分都是三個字母組成的。像下面的三元詞表T(Most Frequent Three-LetterWords),其中the的頻率顯著高於其餘的詞,但可讀文本中出現的三元詞並不一定都出現在T裏面,因爲三元詞包含上千種,且不同類型的文本頻率會有很大不同。例如個別名詞TCP,在計算機網絡的相關文章中就有可能頻繁出現。

對於這樣的問題,我們就不能像二元詞頻率篩選一樣通過篩選三元詞來保證它們一定出現在T內,所以當我們遇到衝突時,例如


    判斷一元二元詞分析成不成功,就可以通過計數器的大小作爲標準,這裏設定一個threshold,當threshold* 密文三元詞種類個數 > 計數器值時,我們認爲前面的破譯結果就是正確的,否則返回到二元詞回溯繼續匹配。threshold可以作爲破譯準確度的控制指標,不同值會影響篩查的嚴格程度,當threshold = 1時就認爲密文中出現的所有三元詞都會出現在T中,這對小文本較管用。

下面就是一個判斷條件

    if (tripleDecode(simpleCipherArray[2], letterDecode) >= Cryptanalysis.threshold * simpleCipherArray[2].size())

threshold = 0.8是經過後來大量的文本測試所得出來的一個較通用的且破譯準確度高的值

/**
	 * threshold:<strong> the strictness of filter</strong></br>
	 * set less than 0.8 if cipher is large, <br>
	 * over 0.8 you can get better result if cipher is short
	 */
	static final float threshold = 0.8f; 


2.3 最後的窮舉完整破譯

剩下的最後一步,到這裏至少60%的字母已經被破譯出來了,剩下的未知字母中大都屬於比較偏僻的字母,類似x,z等。他們在文本中出現的頻率也不高,且可以從頻率分佈圖1中看出他們頻率都比較相近,這就很難再使用頻率分析的方法對它們做進一步分析。

剩下10個左右的未解祕字符其實實際看來密鑰空間並不是10!,隨機抽出一個單詞,它可能存在的未破譯單詞是單詞長度的一半,通常一個單詞長度不會超過10,那麼也就是5!大小的密鑰空間。所以我們完全可以直接用窮舉的方式對未破譯的單詞進行窮舉,然後到詞典中去查找,查找失敗則替換成另一個k,當密鑰空間K已經遍歷一遍後依然找不到,那我們默認詞典單詞缺失,放棄這個密文單詞繼而破譯下一個。

前面我們都無一例外的在做一件事,就是爲了這一步。我們知道破譯密文最通用最有效的方法就是窮舉密鑰空間。但可不可行就需要看密鑰空間的大小了,窮舉的空間太大,我們就無法在理想時間內得到解。如密文單詞 xogokgoxu 這時可能變成xaragraxh,x從初始密鑰空間{a-z}現在變爲{p,v, c},且這個單詞裏只剩下2個字母未破譯,蠻力法就顯得十分有效了。這時很快就能找到明文是paragraph。

窮舉過程

假設x-{p, v, c}, u-{h, k},對窮舉可以用棧來保存當前配對的字符位置,或是先前一維數組的形式。算法思想也是一個回溯的過程,維護好當前的對應關係即可。


譯碼效果

加密文本a1 短文本,單詞量1300 words,圖3.1


                                          圖 3.1 a1(1300 words)

加密後密文

                                               圖 3.1.1 a1_cipher

譯碼結果


                                               圖 3.1.2 a1_decode

準確率爲93%,錯誤2個,此時threshold = 0.8。

設爲
	static final float threshold = 0.8f; 

這時的結果見圖3.1.3,正確率100%。

                                               圖3.1.3 a1_decode_2

選其他較大的文本再做測試

    

                  圖3.2 大文本 (400,000words)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章