[古典密码]:PlayFair cipher(Playfair密码)
2016-09-10 14:52
316 查看
来源于我的博客
1.编制密码表
构造一个5*5的密码表,表格填充关键字(字母不重复),之后按字典序填充密码表中没有的字母,需要注意的是5*5表格只能放25个字母,剩下一个字母需要选择已经放入表的一个作为替代,这里习惯性将J省略,I/J共用。以关键字为PLAYFAIR
EXAMPLE为例
P | L | A | Y | F |
I/J | R | E | X | M |
B | C | D | G | H |
K | N | O | Q | S |
T | U | V | W | Z |
2.整理明文
由于PalyFair成对字母加密的特性,要对明文进行分组处理:两个不同的字母一组,如果字母相同需要添加冗余(指定一个字母)保持其不同;
最后如果有单个字母同样需要添加冗余使其成对。
以明文“Things are not always what they see”为例(指定W为替代字母)
整理后变成:“TH IN GS AR EN OT AL WA YS WH AT TH EY SE EW”
3.加密
根据成对字母在字母表中的相对位置进行替代主要分两类:
在一条线上(行相同或列相同)
x相同,就取x+1位置的字母(mod 5,即最右边+1=最左边的):
y相同,就取y+1位置的字母(mod 5,即最下边+1=最上边的):
AL=YA
P | L | A | Y | F |
I/J | R | E | X | M |
B | C | D | G | H |
K | N | O | Q | S |
T | U | V | W | Z |
取两点为顶点的矩形,矩形的另外两点即为密文
注意的是顺序:横坐标保持不变,纵坐标改为pair的纵坐标
T-Z H-B I-R K-N 他们的横坐标均相同
TH=ZB
P | L | A | Y | F |
I/J | R | E | X | M |
B | C | D | G | H |
K | N | O | Q | S |
T | U | V | W | Z |
P | L | A | Y | F |
I/J | R | E | X | M |
B | C | D | G | H |
K | N | O | Q | S |
T | U | V | W | Z |
#include#include#includeusing namespace std; //string keyWord = { "MoonCake" }; string keyWord = { "PLAYFAIR EXAMPLE" }; string alphabet = { "ABCDEFGHIKLMNOPQRSTUVWXYZ" }; char a[5][5] = { " " }; pair getPosi(char c) { for (int i = 0;i < 5;i++) { for (int j = 0;j < 5;j++) { if (c == a[i][j]) return make_pair(i,j); } } return make_pair(6, 6);//(5*5缺少一个字母)失败 } string SplitWord_(string f) { string g; int count_g = 0; int char_c = 0; //作简单分割 for (int i = 0;i < f.size();) { for (int j = 0;j < 2;j++) { if ((int)(f[i])>64 && (int)(f[i]) < 91) { //g[count_g++] = f[i]; string t_f; t_f.resize(1); t_f[0] = f[i]; g.append(t_f); char_c++; } if (((int)(f[i]) > 96) && ((int)(f[i]) < 123)) { //g[count_g++] = (char)((int)f[i] - 32); string t_f; t_f.resize(1); t_f[0]= (char)((int)f[i] - 32); g.append(t_f); char_c++; } if (char_c == 2&&i!=f.size()&& i != f.size()-1) { //g[count_g++] = ' '; g.append(" "); char_c = 0; } i++; } } //cout << g << "e"<<endl; return g; } bool is_dup(string g,int &posi) { for (int i = 0;i < g.size()-1;i++) { if (((int)(g[i]) > 64) && ((int)(g[i]) < 91)&& ((int)(g[i+1]) > 64) && ((int)(g[i+1]) < 91)) { if (g[i] == g[i + 1]) { posi = i; posi++; return true; } } } return false; } string SplitWord(string f, char replace) { string g = SplitWord_(f); //插值(replace)去除重复 int posi = 0; string re; re.resize(1); re[0] = replace; while (is_dup(g,posi)) { g.insert(posi,re); g = SplitWord_(g); } //判断结尾是否成对 if ((g[g.size() - 2]) < 64 || (g[g.size() - 2]) > 91) { g.insert(g.size(), re); } //明文整理完成 return g; } void CreateMatrix() { int row = 0; int colom = 0; for (int i = 0;i < keyWord.size();i++) { if (keyWord[i] == ' ') continue; if ((int)keyWord[i]>96 && (int)keyWord[i] < 123) { keyWord[i] = (char)((int)keyWord[i] - 32); } bool noMatch = true; for (int x = 0;x < 5;x++) { for (int y = 0;y < 5;y++) { if (a[x][y] == keyWord[i]) { noMatch = false; } } } if (noMatch) { a[row][colom] = keyWord[i]; if (++colom > 4) { colom = colom % 5; row++; } } } // 填充剩余字母 for (int i = 0;i < alphabet.size();i++) { bool noMatch = true; for (int x = 0;x < 5;x++) { for (int y = 0;y < 5;y++) { if (a[x][y] == alphabet[i]) { noMatch = false; } } } if (noMatch) { a[row][colom] = alphabet[i]; if (++colom > 4) { colom = colom % 5; row++; } } if (row == 5) break; } //填充完成 } void PrintMatrix() { for (int i = 0;i < 5;i++) { for (int j = 0;j < 5;j++) { cout << a[i][j] << " "; } cout << endl; } } void encrypt(){ //create 5*5 Matrix CreateMatrix(); string f = { "Things are not always what they see" }; f = { "MY Name IS ATUL" }; //整理明文 string g=SplitWord(f, 'W'); PrintMatrix(); cout << g << endl; //加密 for (int i = 0;i < g.size()-1;) { if (getPosi(g[i]).first != getPosi(g[i + 1]).first&&getPosi(g[i]).second != getPosi(g[i + 1]).second) {//对角 char gi = g[i]; char giPlus = g[i + 1]; g[i] = a[getPosi(gi).first][getPosi(giPlus).second]; g[i + 1] = a[getPosi(giPlus).first][getPosi(gi).second]; } if (getPosi(g[i]).first == getPosi(g[i + 1]).first&&getPosi(g[i]).second != getPosi(g[i + 1]).second) {//同x轴 换成对应位于y+1的字母,越界则为最上面 char gi = g[i]; char giPlus = g[i + 1]; int giy = getPosi(gi).second; giy = (giy+1) % 5; int giPlusy = getPosi(giPlus).second; giPlusy = (giPlusy+1) % 5; g[i] = a[getPosi(gi).first][giy]; g[i + 1] = a[getPosi(giPlus).first][giPlusy]; } if (getPosi(g[i]).first != getPosi(g[i + 1]).first&&getPosi(g[i]).second == getPosi(g[i + 1]).second) {//同y轴 换成对应位于x+1的字母,越界则为最上面 char gi = g[i]; char giPlus = g[i + 1]; int gix = getPosi(gi).first; gix = (gix+1) % 5; int giPlusx = getPosi(giPlus).first; giPlusx = (giPlusx+1) % 5; g[i] = a[gix][getPosi(gi).second]; g[i + 1] = a[giPlusx][getPosi(giPlus).second]; } i+=3; } cout << g << endl; } void decrypt() { CreateMatrix(); string g = { "XF OL IX MK PV LR" }; cout << g << endl; //解密 for (int i = 0;i < g.size() - 1;) { if (getPosi(g[i]).first != getPosi(g[i + 1]).first&&getPosi(g[i]).second != getPosi(g[i + 1]).second) {//对角 char gi = g[i]; char giPlus = g[i + 1]; g[i] = a[getPosi(gi).first][getPosi(giPlus).second]; g[i + 1] = a[getPosi(giPlus).first][getPosi(gi).second]; } if (getPosi(g[i]).first == getPosi(g[i + 1]).first&&getPosi(g[i]).second != getPosi(g[i + 1]).second) {//同x轴 换成对应位于y-1的字母,越界则为最上面 char gi = g[i]; char giPlus = g[i + 1]; int giy = getPosi(gi).second; giy = (giy - 1)>=0?(giy - 1):4; int giPlusy = getPosi(giPlus).second; giPlusy = (giPlusy - 1)>=0? (giPlusy - 1):4; g[i] = a[getPosi(gi).first][giy]; g[i + 1] = a[getPosi(giPlus).first][giPlusy]; } if (getPosi(g[i]).first != getPosi(g[i + 1]).first&&getPosi(g[i]).second == getPosi(g[i + 1]).second) {//同y轴 换成对应位于x-1的字母,越界则为最上面 char gi = g[i]; char giPlus = g[i + 1]; int gix = getPosi(gi).first; gix = (gix - 1)>=0 ? (gix - 1):4; int giPlusx = getPosi(giPlus).first; giPlusx = (giPlusx - 1)>=0? (giPlusx - 1):4; g[i] = a[gix][getPosi(gi).second]; g[i + 1] = a[giPlusx][getPosi(giPlus).second]; } i += 3; } cout << g << endl; } int main() { encrypt(); cout << "加密完成,立即解密" << endl; decrypt(); cout << "解密完成" << endl; return 0; }
相关文章推荐
- 波雷费密码 Playfair Cipher 及 希尔密码 Hill Cipher 原理简述
- 四种古典密码的C++实现(3)-----Playfair密码
- Playfair Cipher
- [古典密码]:Caesar cipher(凯撒密码)
- [古典密码]:Hill cipher(希尔密码)
- [古典密码]:Vigenere cipher 维吉尼亚密码
- Polybius密码(Polybius Cipher)
- 古典密码之维吉尼亚密码破解思路
- 解决Field 'ssl_cipher' doesn't have a default value的问题(mysql创建用户名和密码)
- 密码学基础知识(三)古典密码
- sgu297:Fair-play(水题)
- 古典密码(Hill加密算法)
- 实验吧-古典密码
- 古典密码(Hill加密算法)
- Acient Cipher 古老的密码 快速排序法
- Fair-Play:The quick brown fox jumps over the lazy dog!
- Playfair 加密算法
- 关于古典密码的编制理论基础
- 决斗场 - 实验吧 密码学 古典密码
- [原]古典密码学