密碼學(xué) 愷撒移位密碼

2020-07-29 15:50 更新

簡介

愷撒移位密碼 因據(jù)說愷撒是率先使用加密函的古代將領(lǐng)之一,因此這種加密方法被稱為愷撒密碼。這是一種簡單的加密方法,這種密碼的密度是很低的,只需簡單地統(tǒng)計字頻就可以破譯。 現(xiàn)今又叫“移位密碼”,只不過移動的位數(shù)不一定是3位而已。

故事

將替換密碼用于軍事用途的第一個文件記載是愷撒著的《高盧記》。愷撒描述了他如何將密信送到正處在被圍困、瀕臨投降的西塞羅。其中羅馬字母被替換成希臘字母使得敵人根本無法看懂信息。 蘇托尼厄斯在公元二世紀(jì)寫的《愷撒傳》中對愷撒用過的其中一種替換密碼作了詳細(xì)的描寫。愷撒只是簡單地把信息中的每一個字母用字母表中的該字母后的第三個字母代替。這種密碼替換通常叫做愷撒移位密碼,或簡單的說,愷撒密碼。 盡管蘇托尼厄斯僅提到三個位置的愷撒移位,但顯然從1到25個位置的移位我們都可以使用, 因此,為了使密碼有更高的安全性,單字母替換密碼就出現(xiàn)了。 如: 明碼表 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 密碼表 Q W E R T Y U I O P A S D F G H J K L Z X C V B N M 明文 F O R E S T 密文 Y G K T L Z 只需重排密碼表二十六個字母的順序,允許密碼表是明碼表的任意一種重排,密鑰就會增加到四千億億億多種,我們就有超過4×1027種密碼表。破解就變得很困難。

詳解

加密時每一個字母向前推移 k 位,例如當(dāng) k=5 時,置換表如下圖:

于是我們把每個字母對應(yīng)一個數(shù)字分別從0~25

則 Caesar 加密變換實際上是: c = (m + k) mod 26 其中 m 是明文對應(yīng)的數(shù)據(jù),c 是與明文對應(yīng)的密文數(shù)據(jù),k 是加密用的參數(shù),也稱為密鑰。 很容易得到相應(yīng)的 Caesar 解密變換是: m = D(c) = (c – k) mod 26

例子

1.手動完成 Caesar 密碼 當(dāng)密鑰 k=3 時,對應(yīng)明文:data security has evolved rapidly 的密文:GDWD VHFXULWB KDV HYROYHG UDSL 2.Caesar 加密 編碼實現(xiàn)“Caesar 密碼”。在明文輸入?yún)^(qū)輸入明文:data security has evolved rapidly。將密鑰 k 調(diào)節(jié)到 3,查看相應(yīng)的密文,并與你手動加密的密文進(jìn)行比較。 m = D(c) = (c – k) mod 26

C++代碼

#include < iostream >
using namespace std;
int main() {
    char c[27] = {       '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',' '
    };
    char mi[27];
    int a = 1,
    b = 3;
    int i = 0;
    for (i = 0; i < 26; i++) {
        mi[i] = c[(b + i * a) % 26]; //按順序?qū)?yīng)的密碼
    }
    char in [1024] = {
        '/0'
    };
    mi[26] = {
        ' '
    };
    gets_s( in );
    for (i = 0; i < 10; i++) cout << in[i];
    for (i = 0; i < 26; i++) {
        cout << c[i] << mi[i] << endl;
    }
    cout << "解密為:" << endl;
    int k;
    for (k = 0; k < 30; k++) {
        for (i = 0; i <= 26; i++) {
            if ( in [k] == mi[i]) {
                cout << c[i];
                break;
            }
        }
    }
    cout << "加密為" << endl;
    for (k = 0; k < 30; k++) {
        for (i = 0; i <= 26; i++) {
            if ( in [k] == c[i]) {
                cout << mi[i];
                break;
            }
        }
    }
}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號