Playfair 加密算法
来源:互联网 发布:石油进口数据 编辑:程序博客网 时间:2024/06/16 15:31
Playfair 加密原理
Playfair 密码将明文中的双字母组合作为一个单元对待,并将这些单元转换为密文双字母组合。
Playfair 密码基于一个 5x5 字母矩阵,该矩阵使用密钥来构造,其构造方法是:
从左至右,从上至下依次填入关键词的字母(去除重复的字母),然后以字母表顺序依次填入其他的字母。(字母 I 和 J 被当做一个字母)
对每一对明文字母 p1、p2 的加密办法如下:
- 若 p1=p2,则插入一个字母(例如X,需事先约定)于重复字母之间;
- 若明文字母数为奇数时,则在明文的末端添加某个事先约定的字母作为填充;
- 若 p1、p2 在同一行时,则对应密文 c1、c2 分别是紧靠 p1、p2 右端的字母。(最后一列的右方为第一列);
- 若 p1、p2 在同一列时,则对应密文 c1、c2 分别是紧靠 p1、p2 下方的字母。(最后一行的下方为第一行);
- 若 p1、p2 不在同一列、同一行时,则 c1、c2 是由 p1、p2 确定的矩形的剩余两个角的字母,c1 与 p1 同行,c2 与 p2 同行。
具体实现如下:
/* 约定:若明文字母数为奇数时, 明文末尾添加字母 p2 = p1 + 1 * 明文对中的两个字母相等时,中间插入‘X’ */#include <iostream>#include <cstring>using namespace std;char X = 'X'; char K[] = "fivestars";char M[] = "Playfair cipher was actually invented by wheatstone";//字母是否已在矩阵中(已赋值的1是J的位置)int flag[26]={ 0,0,0,0,0, 0,0,0,0,1, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0 }; //判断字符是否存在于数组,若不存在则加入int duplicate(char a, char b[]){ int i, flag = 1; //flag=1,字符第一次出现 for (i=0; i<strlen(b); i++) { if(b[i]==a) { //a[i]在目标串中存在,即重复 flag = 0; } } return flag; }//初始化密钥,a[]原始密钥,b[]目标密钥 void initKey(char a[], char b[], int flag[]){ int i, j, k=0, flag; for (i=0; a[i]!='\0'; i++) { if (a[i]==' ') //跳过空格 continue; if (a[i]>='a' && a[i]<='z') a[i] = a[i]-32; //密钥小写转大写 if(a[i]=='J') a[i] = 'I'; //密钥 J 都变为 I if (duplicate(a[i],b)) { //赋值新字符,或跳过重复字符, b[strlen(b)] = a[i]; //字符加入目标串结尾 flag[a[i]-'A'] = 1; //标记在字母表中已存在 } } b[strlen(b)] = '\0'; cout << "Init K : " << b << endl << endl;}//创建字母表(这里用了一维数组来模拟,当然也可用二维)void createTable(char key[]){ int i; for (i=0; i<26; i++) if (flag[i]==0) key[strlen(key)] = i+'A'; //剩余字母无重复地添加到 key (共25个) key[strlen(key)] = '\0'; for (i=0; i<25; i++) { cout << key[i]; if((i+1)%5==0) cout << endl; //每隔5个换行 } cout << endl;}//初始化明文void initPlain(char a[], char b[]){ int i, j=0, k=0, flag; for (i=0; a[i]!='\0'; i++) { if (a[i]==' ') //跳过空格 continue; if (a[i]>='a' && a[i]<='z') a[i] = a[i]-32; //小写转大写 if (a[i]=='J') a[i] = 'I'; //J 都变为 I b[j] = a[i]; j++; //j 为新数组的长度 if (j%2==0) { //(1)判断明文对两字母是否重复,重复则用规定的 X 代替 if (b[j-1]==b[j-2]) { b[j] = b[j-1]; b[j-1] = X; j++; } } if (strlen(b)%2) //(2)若字母数为奇数,在明文末尾添加字母p2 = p1+1 b[strlen(b)] = b[strlen(b)-1] + 1; } b[strlen(b)] = '\0'; cout << "Init M : " << b << endl << endl;}//获取明文在字母表中的二维坐标void grid(char a[], char c, int &x, int &y){ int k = 0; for (k=0; a[k]!='\0'; k++) { if(a[k] == c) { x = k/5; y = k%5; } }} void encrypt(char key[], char plain[], char cipher[]){ int k, i,j, m,n; for (k=0; plain[k]!='\0'; k+=2) { grid(key, plain[k], i, j); grid(key, plain[k+1], m, n); if (i==m) { // (3) 同一行 cipher[k] = key[i*5+(j+1)%5]; cipher[k+1] = key[m*5+(n+1)%5]; } else if (j==n) { // (4) 同一列 cipher[k] = key[(i+1)%5*5+j]; cipher[k+1] = key[(m+1)%5*5+n]; } else { // (5) 斜对 cipher[k] = key[i*5+n]; cipher[k+1] = key[m*5+j]; } } cout << "Encrypt: " << cipher << endl;}int main(){ int i,j,k; int c = 0; char key[100]={0}, plain[100]={0}, cipher[100]={0}; cout << "K: " << K << endl; cout << "M: " << M << endl << endl; initKey(K, key, flag); //初始化密钥 createTable(key); //创建字母表 initPlain(M, plain); //初始化明文 encrypt(key, plain, cipher); //加密 return 0;}
测试
0 0
- playfair加密算法
- Playfair 加密算法
- Playfair Cipher
- playfair 加密
- Playfair密码
- Playfair密码
- Playfair密码
- 密码学---PlayFair
- playfair密码
- playfair加密
- Playfair密码
- playFair密码
- playfair密码
- Playfair密码
- [古典密码]:PlayFair cipher(Playfair密码)
- 密码学(playfair)
- C基础/PlayFair加密
- Playfair密码变种加密
- WebService基础教程之二(Ajax调用WebService服务)
- BadVPN详解之--组网原理剖析
- Servlet3.0新特性(从注解配置到websocket编程)
- 仿ios各种对话框实现,妈妈再也不用担心了
- Error:Execution failed for task >!zip.isFile()
- Playfair 加密算法
- 有趣的题目:四色着色问题算法研究
- spring_mybatis.xml 中国
- spring_json.xml
- EmpMapper.xml
- 有道词典简易客户端
- Unreal4+Qt+Plugins(unrealcv)安装教程
- shell spawn
- centos安装jdk、tomcat、mysql环境