資訊安全-1:python之playfair密碼演算法詳解[原創]

來源:互聯網
上載者:User

標籤:logs   比較   部落格   接收   gen   過程   重要   range   list   

轉寄註明出處: http://www.cnblogs.com/0zcl/p/6105825.html 

 

一、基本概念

 

  1. 古典密碼是基於字元替換的密碼。加密技術有:Caesar(愷撒)密碼、Vigenere(維吉尼爾)密碼、Playfair密碼、Hill密碼……
  2. 明文:未經過加密的資訊;密文:加密後的資訊
  3. 加密解密的過程:如

 

 

二、Caesar密碼

  這裡我先簡單講下愷撒密碼,鹹覺挺簡單的,後面再主要講Playfair演算法原理與編程。

基本原理:

在開拓羅馬帝國的時候,愷撒擔心信使會閱讀他送給士兵的命令,因此發明了對命令進行加密的演算法--愷撒密碼器

愷撒密碼器挺簡單的:把字母表中的每個字母向前迴圈移動3位

  • 加密資訊將字母向前移動三位
  • 解密資訊將字母向後移動三位
  • 移動的位元是關鍵,稱之為密鑰
  • 加密和解密的密鑰是相同的,我們稱之為對稱密碼器

 

數學表達

愷撒密碼的密碼編譯演算法表示為:C=E(p)=(p+3) mod 26

愷撒密碼的解密演算法表示為:p=D(C)=(C-3) mod 26

 

改進的愷撒密碼

明文的發送方和接收方事先協商好一個密鑰K(1<=K<=25),則:

愷撒密碼的密碼編譯演算法表示為:C=E(p)=(p+K) mod 26

愷撒密碼的解密演算法表示為:p=D(C)=(C-K) mod 26

 

 

三、Playfair密碼

基本原理

Playfair演算法基於一個5*5的字母矩陣,該矩陣使用一個關鍵詞構造,方法是按從左至右、從上到下順序,填入關鍵詞的字母(去除重複字母)後,將字母表其作餘字母填入。

例如: 關鍵詞取:monarchy時,字母矩陣為如示(矩陣只能放25個字母,I與J同)

 

加密規則(重要)

Playfair密碼編譯演算法是先將明文按兩個字母一組進行分組,然後在矩陣中找對應的密文。

取密文的規則如下:

  1. 若明文出現相同字母在一組,則在重複的明文字母中插入一個填充字母(eg:z)進行分隔後重新分組(eg: balloon被重新分組為ba lz lo on)
  2. 若分組到最後一組時只有一個字母,則補充字母z
  3. 若明文字母在矩陣中同行,則迴圈取其右邊下一個字母為密文(矩陣最右邊的下一個是最左邊的第一個)(eg: ar被加密為RM)
  4. 若明文字母在矩陣中同列,則迴圈取其下邊下一個字母為密文(矩陣最下邊的下一個是最上邊的第一個)(eg: mu被加密為CM)
  5. 若明文字母在矩陣中不同行不同列,則取其同行且與同組另一字母同列的字母為密文(eg: hs被加密為BP,ea被加密為IM或JM)

PS:上述規則第一次看時挺煩的,但照著例子看就一定可以看懂的!

舉例(這個例子後面測試會用到的):

明文為we are discovered save yourself,分組成為we ar ed is co ve re ds av ey ou rs el fz; 

用上述矩陣加密後的密文為:UG RM KC SX HM UF MK BT OX GC MV AT LU KV

 

 

 四、Playfair演算法編程

這裡我不想直接貼代碼。想仔細說下編程的思路以及中間遇到的一些問題。因為剛開始百度參考別人的部落格都是直接貼代碼,沒說思路,看代碼又不大懂。搞得我都是自己編的代碼。

 

流程圖(重要)

我畫的流程圖網址https://www.processon.com/diagraming/5839ae8de4b086d1e7cba620

媽呀!流程圖已經把我想說的大都說了~~尷尬~

如果加密做了,解密真的很簡單的。接下來說下我遇到的幾個問題,卡住挺久的~

 

 

 問題及分析

 問題1. 一組字母是重複明文字母,則插入字母Z(我設的,你也可以設別的),如何???

我剛開始的做法是迴圈明文列表,依次找出第奇數(為什麼不先找偶數?先找偶數之後就得去找下一個元素(奇數),怕下標越界)個元素,然後比較奇數前面一個元素(偶數)是否相同,相同則插入字母Z。然而問題來了?每次我插入一個Z,列表及下標就會變化,這樣就得重新迴圈插入才行!

1     for i in range(len(list_clear_text)):2         if(i % 2 == 1):   #列表中的第d奇數個3             if(list_clear_text[i] == list_clear_text[i-1]):   #第奇數個與前一個(偶數)是否相同4                 list_clear_text.insert(i, "Z")   #有重複明文字母則插入一個填充字母Z 並且退出迴圈5                 break

然後我們用個while迴圈調用上面代碼就可以了。接下來的問題是:如何退出while迴圈,即如何判斷列表沒有一組字母是重複的明文字母。這裡我想了想,決定用一個count來計數,每一組明文字母不相同時,則count+1,當 count == int(len(list_clear_text) / 2)時便可退出迴圈!

 1 #處理一組字線是重複明文字母 2 def deal_repeat(list_clear_text): 3     count = 0    #計算資料行表中有多少組是不同的 4     flag = False 5     for i in range(len(list_clear_text)): 6         if(i % 2 == 1):   #列表中的第d奇數個 7             if(list_clear_text[i] == list_clear_text[i-1]):   #第奇數個與前一個(偶數)是否相同 8                 list_clear_text.insert(i, "Z")   #有重複明文字母則插入一個填充字母Z 並且退出迴圈 9                 break10             if (list_clear_text[i] != list_clear_text[i - 1]):11                 count += 112                 if count == int(len(list_clear_text) / 2):13                     flag = True14 15     return list_clear_text,flag   #返回的是元組 (list_clear_text, flag)

啪啪啪!問題解決!接下來說個解密時遇到的問題。

 

問題2:解密時先判斷列表最後一個是否Z,是的話刪除,接著問題來了,如何刪除加密時在一組重複的明文中填充的字母Z???

我剛開始的做法是先判斷(decryption_list[i]為第偶數個,若與decryption_list[i+2]相同,並且中間decryption_list[i+1] == "Z"等於Z,則刪除中間的Z)

1     for i in range(len(decryption_list)):2         if i % 2 == 0:3             if i+2 < len(decryption_list) and 4                             decryption_list[i] == decryption_list[i+2] and decryption_list[i+1] == "Z":5                 delete_list.pop(i+1)

為了方便看上面的判斷,我貼下測試:

請輸入明文:aabbbcccc[‘a‘, ‘a‘, ‘b‘, ‘b‘, ‘b‘, ‘c‘, ‘c‘, ‘c‘, ‘c‘][‘a‘, ‘Z‘, ‘a‘, ‘b‘, ‘b‘, ‘Z‘, ‘b‘, ‘c‘, ‘c‘, ‘Z‘, ‘c‘, ‘Z‘, ‘c‘][‘a‘, ‘Z‘, ‘a‘, ‘b‘, ‘b‘, ‘Z‘, ‘b‘, ‘c‘, ‘c‘, ‘Z‘, ‘c‘, ‘Z‘, ‘c‘, ‘Z‘]      #最後添加字母Z

問題來了,和問題1一樣,每刪除一個Z,列表與下標也隨之變化了啊!怎麼辦??像問題1那樣迴圈刪除?這樣搞,我有幾條命都不夠用來打代碼。有沒有簡單的?啪啪啪。靈光一現,我可以從後往前刪除,這樣就不怕列表下標變化了,用一個空列表來裝我要刪除元素的下標。

 1     delete_list = [] 2     for i in range(len(decryption_list)): 3         if i % 2 == 0:          #第偶數個 4             #不越界 5             if i+2 < len(decryption_list) and  6                             decryption_list[i] == decryption_list[i+2] and decryption_list[i+1] == "Z": 7                 delete_list.append(i+1) 8                 #decryption_list.pop(i+1) 9     delete_list.reverse()     #反序,從後往前刪除,每次刪完下標就不會再變化,我真是太聰明了!10     for i in delete_list:11         print(i)12         decryption_list.pop(i)

 

 

問題3:我設定的是插入Z,當時我想的是如果一組重複的明文剛好是zz,那還能插入Z(我設定的)?以及如果明文列表最後一個剛好是z,那我還能在最後補充Z??

於是,測試如下:

 View Code

通過測試,也沒問題,因為解密時會把多餘的Z刪除。(看來我想多了~)

 

 

問題4: 好尷尬的BUG

加密時,不論時文abc, 還是abcz,加密後的密文均為BJDU,那慘了,那BJDU解密時,是abc?還是abcz??

Please input E for encryption or D for decryption:E請輸入明文(小寫字母):ABC[‘A‘, ‘B‘, ‘C‘][‘A‘, ‘B‘, ‘C‘][‘A‘, ‘B‘, ‘C‘, ‘Z‘]加密成功!密文:BJDUPlease input E for encryption or D for decryption:D請輸入密文(大寫字母/偶數):BJDU解密成功!明文:ABCPlease input E for encryption or D for decryption:E請輸入明文(小寫字母):abcz[‘a‘, ‘b‘, ‘c‘, ‘z‘][‘a‘, ‘b‘, ‘c‘, ‘z‘][‘a‘, ‘b‘, ‘c‘, ‘z‘]加密成功!密文:BJDUPlease input E for encryption or D for decryption:D請輸入密文(大寫字母/偶數):BJDU解密成功!明文:ABCPlease input E for encryption or D for decryption:

不管了,大家不必死鑽這個BUG,如果有啥好辦法可以與我交流下,我吃飯去了……

 

 五、總結

 

  • 有半個月沒用python了,列表操作有些竟然忘了。尷尬~
  • list.pop()刪除指定下標的元素,預設刪除最後一個元素
  • 列表的list.reverse()傳回值是None
  • 方法return 1,2  其實是返回一個元組(1, 2)
  • print(int(7/2)) 輸出3

 

 

 原始碼

 

 View Code

 

 測試案例

 View Code

 

資訊安全-1:python之playfair密碼演算法詳解[原創]

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.