Enigma加解密算法实现C++

Enigma加解密算法实现C++

刚刚接触密码学,就打算用C++实现一下Enigma的加解密。加密的思想就是非常经典的多表代换。
德国二战时期的密码系统:亚瑟·谢尔比乌斯
为了战胜enigma,英国在布莱榭丽公园的小木屋里建起了密码学校,这里聚集着各种不同寻常的怪才数学家、军事家、心理学家、语言学家、象棋高手、填字游戏专家,有些人专门负责处理细节,有些人则通过不合常理的思维跳跃来寻找灵感,到二战结束时,这里已经聚集了7000人。
二战成立密码史上的黄金时代。军事科学家估计,盟军对密码的成功破译使得二战至少提前一年结束。
二战结束后,英国并没有透露ENIGMA被破解的秘密,知道二十世纪70年代,各国转向计算机加密的研究,人们才知道布莱榭丽公园的故事。但那时,很多无名英雄已经长眠地下。这其中,天才密码学家图灵的命运最为不幸,他不但没有因为破译受到嘉奖,反而因为“同性恋”而被政府以有伤风化罪起诉。1954年,身心疲惫的图灵服毒自杀,时年42岁。今天,信息学领域最重要的奖项被命名为“图灵奖”,也许是对他的补偿吧。
转轮密码机原理

慢轮子、中轮子和快轮子分别用三个循环链表实现。下面给出慢轮子的定义。

1#include "Node.h" 2class Swheel{ 3private: 4 Node *first; 5 int _key; 6public: 7 Swheel(); 8 ~Swheel(); 9 void run(); 10 int key(); 11 int encrypt(int); 12 int decode(int); 13}; 14Swheel::Swheel(){ 15 // 定义表头 16 first = new Node(23, 13, nullptr); 17 // 定义指针 18 Node *p = first; 19 // 定义轮 20 p->link = new Node(22, 24, nullptr);p = p->link; 21 p->link = new Node(21, 6, nullptr);p = p->link; 22 p->link = new Node(20, 25, nullptr);p = p->link; 23 p->link = new Node(19, 2, nullptr);p = p->link; 24 p->link = new Node(18, 18, nullptr);p = p->link; 25 p->link = new Node(17, 23, nullptr);p = p->link; 26 p->link = new Node(16, 12, nullptr);p = p->link; 27 p->link = new Node(15, 9, nullptr);p = p->link; 28 p->link = new Node(14, 17, nullptr);p = p->link; 29 p->link = new Node(13, 5, nullptr);p = p->link; 30 p->link = new Node(12, 11, nullptr);p = p->link; 31 p->link = new Node(11, 4, nullptr);p = p->link; 32 p->link = new Node(10, 22, nullptr);p = p->link; 33 p->link = new Node(9, 7, nullptr);p = p->link; 34 p->link = new Node(8, 16, nullptr);p = p->link; 35 p->link = new Node(7, 8, nullptr);p = p->link; 36 p->link = new Node(6, 20, nullptr);p = p->link; 37 p->link = new Node(5, 26, nullptr);p = p->link; 38 p->link = new Node(4, 14, nullptr);p = p->link; 39 p->link = new Node(3, 10, nullptr);p = p->link; 40 p->link = new Node(2, 19, nullptr);p = p->link; 41 p->link = new Node(1, 1, nullptr);p = p->link; 42 p->link = new Node(26, 15, nullptr);p = p->link; 43 p->link = new Node(25, 3, nullptr);p = p->link; 44 p->link = new Node(24, 21, first);p->link->link = first; 45 // 定义密钥 46 _key = 0; 47 } 48Swheel::~Swheel(){ 49 Node *p = first; 50 for (int i = 0; i < 26; i++){ 51 p = first->link; 52 delete first; 53 first = p; 54 } 55} 56void Swheel::run(){ 57 first = first->link; 58 _key = (_key + 1) % 26; 59} 60int Swheel::key(){ 61 return _key; 62} 63int Swheel::encrypt(int lIndex){ 64 int rIndex = 0; 65 Node *p = first; 66 Node *q = first; 67 // 输入异常处理 68 if (lIndex < 0 || lIndex >= 26) 69 return -1; 70 // 寻址 71 for (int i = 0; i < lIndex; i++) 72 p = p->link; 73 while (q->rNum != p->lNum){ 74 q = q->link; 75 rIndex++; 76 } 77 return rIndex; 78} 79int Swheel::decode(int rIndex){ 80 int lIndex = 0; 81 Node *p = first; 82 Node *q = first; 83 // 输入异常处理 84 if (rIndex < 0 || rIndex >= 26) 85 return -1; 86 // 寻址 87 for (int i = 0; i < rIndex; i++) 88 p = p->link; 89 while (q->lNum != p->rNum){ 90 q = q->link; 91 lIndex++; 92 } 93 return lIndex; 94} 95 96

节点类

1#pragma once 2class Node{ 3public: 4 int lNum; 5 int rNum; 6 Node *link; 7 Node(int left, int right, Node *l); 8 Node(); 9}; 10Node::Node(int left, int right, Node *l) : lNum(left), rNum(right), link(l) {} 11Node::Node() : lNum(0), rNum(0), link(0) {} 12

对加密解密算法经行封装

1#include "Swheel.h" 2#include "Mwheel.h" 3#include "Qwheel.h" 4#include <string> 5using namespace std; 6class Enigma{ 7private: 8 Swheel s; 9 Mwheel m; 10 Qwheel q; 11 void run(); 12 void loadKey(string); 13 int char2index(char); 14public: 15 string encrypt(string, string); 16 string decode(string, string); 17}; 18void Enigma::run(){ 19 q.run(); 20 if (q.key() == 0) { 21 m.run(); 22 if (m.key() == 0) 23 s.run(); 24 } 25 return; 26} 27int Enigma::char2index(char data){ 28 int index = -1; 29 if (data >= 'A' && data <= 'Z') 30 index = 'Z' - data; 31 if (data >= 'a' && data <= 'z') 32 index = 'z' - data; 33 return index; 34} 35void Enigma::loadKey(string key){ 36 // 密钥异常判定 37 if (key.size() < 3) 38 key = "ZZZ"; 39 // 慢轮密钥 40 int sKey = char2index(key[0]); 41 if (sKey == -1) 42 sKey = 0; 43 while (s.key() != sKey) 44 s.run(); 45 // 中轮密钥 46 int msKey = char2index(key[1]); 47 if (mKey == -1) 48 mKey = 0; 49 while (m.key() != mKey) 50 m.run(); 51 // 快轮密钥 52 int qKey = char2index(key[2]); 53 if (qKey == -1) 54 qKey = 0; 55 while (q.key() != qKey) 56 q.run(); 57 return; 58} 59string Enigma::encrypt(string plainText, string key){ 60 // 密文 61 string cipherText = ""; 62 // 明文序号 63 int index = 0; 64 // 加载密钥 65 loadKey(key); 66 // 加密 67 for (int i = 0; i < plainText.size(); i++) { 68 index = char2index(plainText[i]); 69 if (index == -1) 70 cipherText += plainText[i]; 71 else 72 cipherText += 'Z' - q.encrypt(m.encrypt(s.encrypt(index))); 73 run(); 74 } 75 return cipherText; 76} 77string Enigma::decode(string cipherText, string key){ 78 // 明文 79 string plainText = ""; 80 // 密文序号 81 int index = 0; 82 // 加载密钥 83 loadKey(key); 84 // 解密 85 for (int i = 0; i < cipherText.size(); i++) { 86 index = char2index(cipherText[i]); 87 if (index == -1) 88 plainText += cipherText[i]; 89 else 90 plainText += 'Z' - s.decode(m.decode(q.decode(index))); 91 run(); 92 } 93 return plainText; 94} 95

加解密主函数,下面仅给出加密主函数

1#include "Enigma.h" 2#include <iostream> 3using namespace std; 4int main(){ 5 // 创建密码机 6 Enigma machine; 7 // 输入缓冲 8 char input = '\0'; 9 // 明文 10 string plainText = ""; 11 // 密钥 12 string key = ""; 13 // 密文 14 string cipherText = ""; 15 // 输入 16 cout << "Please input your encrypt key:" << endl; 17 while(true) { 18 input=cin.get(); 19 if(input=='\n') 20 break; 21 key += input; 22 } 23 cout << "Please input that you want to encrypt:" << endl; 24 while(true) { 25 input=cin.get(); 26 if(input=='\n') 27 break; 28 plainText += input; 29 } 30 // 加密 31 cipherText = machine.encrypt(plainText, key); 32 cout << "After encrypt:" << endl; 33 cout << cipherText << endl; 34 system("pause"); 35 return 0; 36} 37

源代码会上传到资源。

代码交流 2021