1. 程式人生 > >小亮學加密解密-----凱撒加密法

小亮學加密解密-----凱撒加密法

a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

1.加密原理

     所謂的“凱撒加密法”,就是將需要加密的原文,逐個字元轉化成其他字元的之後,形成新的密文。

    如上圖,第一行,是所有可以被轉換的字元(為方便顯示,只列舉了26個小寫英文字元),

    第二行,為第一行每個字元對應的索引。

    接著,從1~X(X為需要加密的字元的最大索引值)中,選取一個數字,作為金鑰。

    當我們拿到需要加密的字串時,將字串中每個字元逐一去上圖中尋找,找到其對應的索引,

    之後,將得到的索引與金鑰相加,得到的新索引對應的字元,就是轉換後的新字元;

    如果索引與金鑰相加後大於索引的最大值,則需要從頭尋找對應的新字元。

    舉個例子:

    我們將“helloworld”通過“凱撒加密法”進行加密,金鑰為10,

    我們從第一個字元“h”開始,在上圖中找到h的索引為7,

    將h的索引與金鑰相加,得到17,從上圖找到索引為17的字元為r;

    根據上面的步驟,我們將每個字元按照順序逐個進行轉化,最終得到密文:“rovvygybvn”

    需要注意的是:

                  字元“w”的索引22,加上金鑰後得到32,大於了加密源字元個數26,於是會從0開始繼續尋找,

                  直到找到索引為6(32 - 26 = 6)的字元“g”

  2.解密原理

     由於“凱撒加密法”只是將原文中的每個字元進行轉化得到密文;

     所以在拿到密文後,只要根據金鑰,反推加密過程,即可得到加密前的原文;

     舉個例子:

             密文為“rovvygybvn”,金鑰為10,

             我們先找到密文的第1個字元r的索引,17;

             通過金鑰,反推加密過程,我們可以知道密文在加密前的原文字元索引為7  (17 - 10 = 7),

             從上圖中可知,索引為7的字元為 h;

   需要注意:

           如果密文字元的索引小於金鑰時,

           需要將密文字元的索引與加密源字元個數(上圖最大索引值為26)相加,在減去金鑰,得到原文字元索引,

       例如:

           在解密密文字元g時,由於g的索引為6,小於金鑰10,

           為了找到原文字元,我們需要將g的索引與26(加密源字元個數)相加,

           再與金鑰10相減,即(6 + 26) - 10 = 22,由上圖可知,對應原文字元為w

  通過上述過程,我們將每個字元逐一解密,得到原文“helloworld”             

  具體程式碼實現如下(python實現)

#密文源字串
#encryptSource = r"abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNPOQRSTUVWXYZ1234567890 ,.\"'!"
encryptSource = r"abcdefghigklmnopqrstuvwxyz"

#加密源字元個數
encryptSourceMaxIndex = len(encryptSource)

#金鑰
key = 10

#原文
#source = "Hello,World!"
source = "helloworld"
cryptograph = "rovvygybvn"
#加密方法
def encryptByCaesar(source):
    #密文
    newSource = ""
    #迴圈原文中的每個字元,
    #將每個字元在密文源字串中的索引加上金鑰,得到一個新的索引值
    #如果新索引值大於密文源字元個數,則取新索引與密文源字元個數的差的絕對值
    #根據新索引值,得到加密後的字元,並加入到密文字串的末尾
    for index in range(len(source)):
        #找到原文字元的索引
        oldEncryptSourceIndex = encryptSource.find(source[index])
        #計算轉換後字元的索引
        newEncryptSourceIndex = (oldEncryptSourceIndex + key) if (oldEncryptSourceIndex + key) <= encryptSourceMaxIndex else abs((oldEncryptSourceIndex + key) - encryptSourceMaxIndex)
        #找到新字元,並拼接密文
        newSource += encryptSource[newEncryptSourceIndex]
    return newSource

#解密方法
def unencryptByCaesar(cryptograph):
    #儲存原文字串
    sourceStr = "";
    #迴圈密文中的每個字元,
    #將每個字元在密文源字串中的索引減上金鑰,得到一個新的索引值
    #如果密文索引值小於金鑰,則將密文索引與密文源最大索引值相加,再減去金鑰,得到原文字元索引
    #根據新索引值,得到加密後的字元,並加入到密文字串的末尾
    for index in range(len(cryptograph)):
        #獲取密文字元的索引值
        cryptographIndex = encryptSource.find(cryptograph[index])
        #計算原文字元的索引值
        SourceIndex = (cryptographIndex - key) if cryptographIndex >= key else (cryptographIndex + encryptSourceMaxIndex) - key
        #得到原文字元,拼接原文字串
        sourceStr += encryptSource[SourceIndex]
    return sourceStr

print("source:" + source + ", new source:" + encryptByCaesar(source))
print("cryptograph:" + cryptograph + ", source:" + unencryptByCaesar(cryptograph))