从键盘上接收明文输入,密钥输入。
1.密钥的处理过程:
①将密钥输入全部转换成大写
②并且遇到J字母替换成I字母
③将密钥中重复出现的字母剔除
④按照字母表顺序将密钥未出现的字母进行填充
⑤按照5*5的矩阵输出密钥
2.明文的处理过程:
①将密钥输入全部转换成大写
②并且遇到J字母替换成I字母
③将明文两两一组,如果出现两个字母一样则插入Z,如果相同的字母是Z则依次A-Y的顺序递推到不相等
④经过处理的字符串如果是奇数长度则最后一个字母补充字母,如果最后一个字母是Z则依次A-Y的顺序递推到不相等
3.加密过程
明文两两一组,比如NA TZ TE RI AC KT OA DZ,经过填充处理的密钥是STANDERCHBKFGILMOPQUVWXYZ。每次获取两个字母,则有三种处理方式:
第一种:处于同一行情况
比如NA字母在密钥中的位置分别是第3和第2,
row1=3/5=0,col1=3%5=3,可知N字母在5*5的矩阵中是处于0行3列,同理
row2=2/5=0,col2=2%5=2,可知A字母在5*5的矩阵中是处于0行2列,
此时有行相等,故只用列向右挪动1列,即col1=(col1+1)%5计算出挪动1列后新的列,此时保持row1不变的情况下组成新的位置(row1, col1),然后row1*5+co1计算出在密钥中的新位置
第二种:处于同一列情况
比如AC字母在密钥中的位置分别是第2和第7,
row1=2/5=0,col1=2%5=2,可知A字母在5*5的矩阵中是处于0行2列,同理
row2=7/5=1,col2=7%5=2,可知C字母在5*5的矩阵中是处于1行2列,
此时有列相等,故只用行向下挪动1行,即row1=(row1+1)%5计算出挪动1行后新的行,此时保持col1不变的情况下组成新的位置(row1, col1),然后row1*5+co1计算出在密钥中的新位置
第三种:不在同一列或者同一行需要绘制矩形框
S | T | A | N | D |
E | R | C | H | B |
K | F | G | I | L |
M | O | P | Q | U |
V | W | X | Y | Z |
比如KT字母在密钥中的位置分别是第10和第1,
row1=10/5=2,col1=10%5=0,可知K字母在5*5的矩阵中是处于2行0列,同理
row2=1/5=0,col2=1%5=1,可知T字母在5*5的矩阵中是处于0行1列,行列都不等,故需要绘制矩形框,经过观察可以发现,K的对应点F的坐标就是K的行+T的列,T的对应的S的坐标就是K的行+T的列构成
4.下面是源码(纯c语言代码):
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
void Encryption() {
char MingWen[40];//定义明文字符串
printf("请输入明文");
scanf("%s", MingWen);
for (int i = 0; i < strlen(MingWen); i++) {//将明文字符串小写字母转换为大写字母
if(MingWen[i]>='a'){
MingWen[i] = MingWen[i] - 32;
}
}
for (int i = 0; i <= strlen(MingWen); i++) {//将明文字符串中的J代换为I
if (MingWen[i] == 'J') {
MingWen[i] = 'I';
}
}
for (int i = 0; i < strlen(MingWen); i=i+2) {//遇见两两重复字母情况
if (MingWen[i] == MingWen[i + 1]) {
if (MingWen[i + 1] == 'Z') {//遇见重复字母为Z
for (int j = strlen(MingWen); j >= i; j--) {
MingWen[j+1] = MingWen[j];
}
MingWen[i + 1] = 'A';//在两个Z之间添加个A
}
else {//将重复字母不为Z的两字母之间加Z
for (int j = strlen(MingWen); j > i; j--) {
MingWen[j + 1] = MingWen[j];
}
MingWen[i + 1] = 'Z';
}
}
}
if (strlen(MingWen) % 2 == 1) {//判断新明文是否为奇数,若为奇数且最后一位不为Z,在明文最后一位加Z,
//若为Z,则在最后添加A-Y中不会出现重复情况的字母
if (MingWen[strlen(MingWen)] == "Z"){
MingWen[strlen(MingWen) + 1] = MingWen[strlen(MingWen)];
MingWen[strlen(MingWen)] = 'A';
}
MingWen[strlen(MingWen)+1]=MingWen[strlen(MingWen)];
MingWen[strlen(MingWen)] = 'Z';
}
char MiYue[30];//定义密钥
printf("请输入密钥");
scanf("%s", MiYue);
for (int i = 0; i < strlen(MiYue); i++) {
MiYue[i] = MiYue[i] - 32;
}//将密钥全部转换为大写
for (int i = 0; i <= strlen(MiYue); i++) {//将密钥中的J代换为I
if (MiYue[i] == 'J') {
MiYue[i] = 'I';
}
}
printf("把J替换成I后的key为:%s\n", MiYue);
for (int i = 0; i <= strlen(MiYue); i++) {
for (int j = 1 + i; j <= strlen(MiYue); j++) {
if (MiYue[j] == MiYue[i]) {
for (int n = j; n < strlen(MiYue); n++) {
MiYue[n] = MiYue[n + 1];
}
i = i - 1;
}
}
}
printf("去重后的key为:%s\n", MiYue);
char Biao[5][5];//定义表
char OtherChar[25] = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
for (int j = 0; j <= strlen(MiYue); j++){
for (int i = 0; i < 26; i++){
if (MiYue[j] == OtherChar[i]) {//去除26字母表中密钥出现过的字母
for (int n = i; n <= 25; n++) {
OtherChar[n] = OtherChar[n + 1];
}
}
}
}
int o = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (j + i * 5 < strlen(MiYue)) {
Biao[i][j] = MiYue[j + i * 5];//先往表中填入密钥字母
}
else {
Biao[i][j] = OtherChar[o];//再填入其他字母
o = o + 1;
}
}
}
printf("填充后的key为:");//打填充的key
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
printf("%c", Biao[i][j]);
}
}
printf("\n");
printf("key形成的矩阵是\n");
for (int i = 0; i < 5; i++) {//打印表
for (int j = 0; j < 5; j++) {
printf("%c ", Biao[i][j]);
}
printf("\n");
}
char MiWen[30];//定义密文
int indexX[2];//表的横坐标
int indexY[2];//表的纵坐标
for (int n = 0; n < strlen(MingWen); n=n+2) {//匹配找到明文字母1对应坐标
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (MingWen[n] == Biao[i][j]) {
indexX[0] = j;
indexY[0] = i;
}
}
}
for (int i = 0; i < 5; i++) {//匹配找到明文字母2对应的坐标
for (int j = 0; j < 5; j++) {
if (MingWen[n + 1] == Biao[i][j]) {
indexX[1] = j;
indexY[1] = i;
}
}
}
if (indexY[0] == indexY[1]) {//纵坐标相同时横坐标向右移动
MiWen[n] = Biao[indexY[0]][(indexX[0]+1)%5];
MiWen[n+1] = Biao[indexY[1]][(indexX[1]+1)%5];
}
else if (indexX[0] == indexX[1]) {//横坐标相同时纵坐标向下移动
MiWen[n] = Biao[(indexY[0]+1)%5][indexX[0]];
MiWen[n + 1] = Biao[(indexY[1]+1)%5][indexX[1]];
}
else {//横纵坐标都不同用对角线字母代换
MiWen[n] = Biao[indexY[0]][indexX[1]];
MiWen[n + 1] = Biao[indexY[1]][indexX[0]];
}
}
printf("J替换成I后的明文是");//打印J替换成I后的明文
for (int i = 0; i < strlen(MingWen)-1; i++) {
printf("%c", MingWen[i]);
}
printf("\n加密后密文为:");//打印密文
for (int i = 0; i < strlen(MingWen); i++) {
printf("%c", MiWen[i]);
}
}
void Declassify() {
printf("还未开发\n");
}
void menu() {
printf("******************\n\n");
printf("1.Playfair加密\n");
printf("2.Playfair解密\n");
printf("0.退出程序\n");
printf("\n******************\n");
int c;
scanf("%d", &c);
getchar();
switch (c) {
case 1: Encryption(); break;
case 2:Declassify(); break;
case 0:exit();
}
}
int main() {
while (1) {
menu();
}
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
void Encryption() {
char MingWen[40];//定义明文字符串
printf("请输入明文");
scanf("%s", MingWen);
for (int i = 0; i < strlen(MingWen); i++) {//将明文字符串小写字母转换为大写字母
if(MingWen[i]>='a'){
MingWen[i] = MingWen[i] - 32;
}
}
for (int i = 0; i <= strlen(MingWen); i++) {//将明文字符串中的J代换为I
if (MingWen[i] == 'J') {
MingWen[i] = 'I';
}
}
for (int i = 0; i < strlen(MingWen); i=i+2) {//遇见两两重复字母情况
if (MingWen[i] == MingWen[i + 1]) {
if (MingWen[i + 1] == 'Z') {//遇见重复字母为Z
for (int j = strlen(MingWen); j >= i; j--) {
MingWen[j+1] = MingWen[j];
}
MingWen[i + 1] = 'A';//在两个Z之间添加个A
}
else {//将重复字母不为Z的两字母之间加Z
for (int j = strlen(MingWen); j > i; j--) {
MingWen[j + 1] = MingWen[j];
}
MingWen[i + 1] = 'Z';
}
}
}
if (strlen(MingWen) % 2 == 1) {//判断新明文是否为奇数,若为奇数且最后一位不为Z,在明文最后一位加Z,
//若为Z,则在最后添加A-Y中不会出现重复情况的字母
if (MingWen[strlen(MingWen)] == "Z"){
MingWen[strlen(MingWen) + 1] = MingWen[strlen(MingWen)];
MingWen[strlen(MingWen)] = 'A';
}
MingWen[strlen(MingWen)+1]=MingWen[strlen(MingWen)];
MingWen[strlen(MingWen)] = 'Z';
}
char MiYue[30];//定义密钥
printf("请输入密钥");
scanf("%s", MiYue);
for (int i = 0; i < strlen(MiYue); i++) {
MiYue[i] = MiYue[i] - 32;
}//将密钥全部转换为大写
for (int i = 0; i <= strlen(MiYue); i++) {//将密钥中的J代换为I
if (MiYue[i] == 'J') {
MiYue[i] = 'I';
}
}
printf("把J替换成I后的key为:%s\n", MiYue);
for (int i = 0; i <= strlen(MiYue); i++) {
for (int j = 1 + i; j <= strlen(MiYue); j++) {
if (MiYue[j] == MiYue[i]) {
for (int n = j; n < strlen(MiYue); n++) {
MiYue[n] = MiYue[n + 1];
}
i = i - 1;
}
}
}
printf("去重后的key为:%s\n", MiYue);
char Biao[5][5];//定义表
char OtherChar[25] = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
for (int j = 0; j <= strlen(MiYue); j++){
for (int i = 0; i < 26; i++){
if (MiYue[j] == OtherChar[i]) {//去除26字母表中密钥出现过的字母
for (int n = i; n <= 25; n++) {
OtherChar[n] = OtherChar[n + 1];
}
}
}
}
int o = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (j + i * 5 < strlen(MiYue)) {
Biao[i][j] = MiYue[j + i * 5];//先往表中填入密钥字母
}
else {
Biao[i][j] = OtherChar[o];//再填入其他字母
o = o + 1;
}
}
}
printf("填充后的key为:");//打填充的key
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
printf("%c", Biao[i][j]);
}
}
printf("\n");
printf("key形成的矩阵是\n");
for (int i = 0; i < 5; i++) {//打印表
for (int j = 0; j < 5; j++) {
printf("%c ", Biao[i][j]);
}
printf("\n");
}
char MiWen[30];//定义密文
int indexX[2];//表的横坐标
int indexY[2];//表的纵坐标
for (int n = 0; n < strlen(MingWen); n=n+2) {//匹配找到明文字母1对应坐标
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (MingWen[n] == Biao[i][j]) {
indexX[0] = j;
indexY[0] = i;
}
}
}
for (int i = 0; i < 5; i++) {//匹配找到明文字母2对应的坐标
for (int j = 0; j < 5; j++) {
if (MingWen[n + 1] == Biao[i][j]) {
indexX[1] = j;
indexY[1] = i;
}
}
}
if (indexY[0] == indexY[1]) {//纵坐标相同时横坐标向右移动
MiWen[n] = Biao[indexY[0]][(indexX[0]+1)%5];
MiWen[n+1] = Biao[indexY[1]][(indexX[1]+1)%5];
}
else if (indexX[0] == indexX[1]) {//横坐标相同时纵坐标向下移动
MiWen[n] = Biao[(indexY[0]+1)%5][indexX[0]];
MiWen[n + 1] = Biao[(indexY[1]+1)%5][indexX[1]];
}
else {//横纵坐标都不同用对角线字母代换
MiWen[n] = Biao[indexY[0]][indexX[1]];
MiWen[n + 1] = Biao[indexY[1]][indexX[0]];
}
}
printf("J替换成I后的明文是");//打印J替换成I后的明文
for (int i = 0; i < strlen(MingWen)-1; i++) {
printf("%c", MingWen[i]);
}
printf("\n加密后密文为:");//打印密文
for (int i = 0; i < strlen(MingWen); i++) {
printf("%c", MiWen[i]);
}
}
void Declassify() {
printf("还未开发\n");
}
void menu() {
printf("******************\n\n");
printf("1.Playfair加密\n");
printf("2.Playfair解密\n");
printf("0.退出程序\n");
printf("\n******************\n");
int c;
scanf("%d", &c);
getchar();
switch (c) {
case 1: Encryption(); break;
case 2:Declassify(); break;
case 0:exit();
}
}
int main() {
while (1) {
menu();
}
return 0;
}
5.运行结果: