- 恺撒密码
- 移位变换
- 仿射变换
- 多表代换
写在前沿的话:
C语言断断续续的学了不少,但还是对结构体、指针、数据结构等了解甚少,所以只能用最基本的循环这些来写,比较繁杂,能力有限,还请谅解,十分欢迎大家批评指正,若有好的优化算法,也欢迎大家交流。第一次写文章,就这样吧。 恺撒密码
//恺撒密码 #include移位变换void CasesarPassward(char *, int ); int main(void) { printf("n******恺撒密码******n"); while(1) { printf("n请输入功能序号:n0.加密n1.解密n2.退出程序n选择功能:"); int function; char ch[1000] = " "; char solve[1000] = " "; scanf("%d", &function); fflush(stdin); switch(function) { case 0: printf("请输入明文:"); gets(ch); CasesarPassward(ch, function); break; case 1: printf("请输入密文:"); gets(solve); CasesarPassward(solve, function); break; case 2 : return 0; break; default: printf("请输入正确的功能编号!"); break; } } } void CasesarPassward(char ch[],int function) { int i = 0; int key = 3; if(function == 0) { while(ch[i] != ' ') { if((ch[i] >= 'a') && (ch[i] <= 'z')) { ch[i] ='a' + (((ch[i] - 'a') + key) % 26); } if((ch[i] >= 'A') && (ch[i] <= 'Z')) { ch[i] ='A' + (((ch[i] - 'A') + key) % 26); } i++; } printf("密文为:%sn", ch); } else if(function == 1) { while(ch[i] != ' ') { if((ch[i] >= 'a') && (ch[i] <= 'z')) { ch[i] ='a' + (((ch[i] - 'a') - key) % 26); } if((ch[i] >= 'A') && (ch[i] <= 'Z')) { ch[i] ='A' + (((ch[i] - 'A') - key) % 26); } i++; } printf("明文为:%sn", ch); } }
//移位变换 #include仿射变换void ShiftTransformation(char *, int, int); int main(void) { printf("n******位移变换******n"); while(1) { printf("n请输入功能序号:n0.加密n1.解密n2.退出程序n选择功能:"); int key; int function; char ch[1000] = " "; char solve[1000] = " "; scanf("%d", &function); printf("n请输入密钥:n"); scanf("%d", &key); fflush(stdin); switch(function) { case 0: printf("请输入明文:"); gets(ch); ShiftTransformation(ch, function, key); break; case 1: printf("请输入密文:"); gets(solve); ShiftTransformation(solve, function, key); break; case 2 : return 0; break; default: printf("请输入正确的功能编号!"); break; } } } void ShiftTransformation(char ch[], int function, int key) //移位变换 { int i = 0; if(function == 0) { while(ch[i] != ' ') { if((ch[i] >= 'a') && (ch[i] <= 'z')) { ch[i] ='a' + (((ch[i] - 'a') + key) % 26); } if((ch[i] >= 'A') && (ch[i] <= 'Z')) { ch[i] ='A' + (((ch[i] - 'A') + key) % 26); } i++; } printf("密文为:%sn", ch); } else if(function == 1) { while(ch[i] != ' ') { if((ch[i] >= 'a') && (ch[i] <= 'z')) { ch[i] ='a' + (((ch[i] - 'a') - key) % 26); } if((ch[i] >= 'A') && (ch[i] <= 'Z')) { ch[i] ='A' + (((ch[i] - 'A') - key) % 26); } i++; } printf("明文为:%sn", ch); } }
//仿射变换 //security vlxijh //THE NATIonAL SECURITY AGENCY //edsgickxhuklzveqzvkxwkzukvcuh #include多表代换#include void AffineTransformation(char *, int, int, int); int GCD(int); int mod_invese(int d, int n); void solve_function(char *); int main(void) { printf("n******仿射变换******n"); while(1) { printf("n请输入功能序号:n0.加密n1.解密n2.解函数n3.退出程序n选择功能:"); int function; int a = 0; int b = 0; char x[4] = " "; char ch[1000] = " "; char solve[1000] = " "; scanf("%d", &function); switch(function) { case 0: printf("请输入加密所用的密钥:(0<=a,b<=25)n"); scanf("%d,%d", &a, &b); while(GCD(a) != 1) { printf("请重新输入密钥:n"); printf("请输入加密所用的密钥:(0<=a<=25)n"); scanf("%d", &a); } fflush(stdin); printf("请输入明文:"); gets(ch); AffineTransformation(ch, a, b, function); break; case 1: printf("请输入解密所用的密钥:(0<=a,b<=25)n"); scanf("%d,%d", &a, &b); while(GCD(a) != 1) { printf("请重新输入密钥:n"); printf("请输入解密所用的密钥:(0<=a<=25)n"); scanf("%d", &a); } fflush(stdin); printf("请输入待解密密文:"); gets(solve); AffineTransformation(solve, a, b, function); break; case 2: printf("请输入方程系数:x,y,m,n:n"); fflush(stdin); gets(x); solve_function(x); break; case 3: return 0; break; default: printf("请输入正确的功能编号!"); break; } } } void AffineTransformation(char ch[], int a, int b, int function) //仿射变换 { int i = 0; if(function == 0) //加密 { while(ch[i] != ' ') { if((ch[i] >= 'a') && (ch[i] <= 'z')) { ch[i] = 'a' + (((ch[i] - 'a') * a + b) % 26); } if((ch[i] >= 'A') && (ch[i] <= 'Z')) { ch[i] = 'A' + (((ch[i] - 'A') * a + b) % 26); } i++; } printf("密文为:%s", ch); } else if(function ==1) //解密 { while(ch[i] != ' ') { if((ch[i] >= 'a') && (ch[i] <= 'z')) { if((ch[i] - 'a' - b) < 0) ch[i] = 'a' + ((ch[i] - 'a' - b) * mod_invese(a, 26)) % 26 + 26;//计算机 n%m=n-m(n/m);(负数时向上取整) else ch[i] = 'a' + ((ch[i] - 'a' - b) * mod_invese(a, 26)) % 26; } if((ch[i] >= 'A') && (ch[i] <= 'Z')) { if((ch[i] - 'A' - b) < 0) ch[i] = 'A' + ((ch[i] - 'A' - b) * mod_invese(a, 26)) % 26 + 26; else ch[i] = 'A' + ((ch[i] - 'A' - b) * mod_invese(a, 26)) % 26; } i++; } printf("明文为:%s", ch); } } int GCD(int a) //判断互素 { int number = 26; int r = a % number; int flag = 0; while(r != 0) { a = number; number = r; r = a % number; } if(number != 1) { return flag; } else { return flag + 1; } } int mod_invese(int d,int n)//求d模n的逆,n 为正整数 { int a;//被除数 int b;//除数 int q;//商 int r; int u = 0; int v = 1; int t; a = n; b = (d >= 0) ? (d % n) : - (d % n);//规定正负数mod(n)都取正; while(b != 0) { q = (int) a / b; r = a - b * q; a = b; b = r; t = v; v = u - q * v; u = t;//把每次没有进行运算的v的值给u }//辗转相除,直到余数b=0,跳出循环 if(a != 1) return 0; return((u < 0) ? u + n : u);//返回的值都是mod(n)后的值,使得最后的值是正数; } void solve_function(char x[]) { int i, j; int a, b; //所要求解的变量 int flag = 0; int time = 1; int k_1 = 0, k_2 = 0; int length; length = strlen(x); int vary[length]; memset(vary,0,sizeof(vary)); for(i = 0; i < length; i++) { if(x[i] >= 'a' && x[i] <= 'z') { vary[i] = x[i] - 'a'; } if(x[i] >= 'A' && x[i] <= 'Z') { vary[i] = x[i] - 'A'; } } while(flag != 2) { k_1 = 0 ; for(i = 0; i < time; i++) { k_2 = 0; for(j=0; j < time; j++) { k_2++; if(((vary[2] + 26 * k_1 - vary[3] - 26 * k_2) % (vary[0] - vary[1])) == 0) flag++; if(((vary[1] * (vary[2] + 26 * k_1) - vary[0] * (vary[3] + 26 * k_2)) % (vary[1] - vary[0])) == 0) flag++; if(flag == 2) break; } k_1++; } time++; } a = ((vary[2] + 26 * k_1 - vary[3] - 26 * k_2) / (vary[0] - vary[1])); b = ((vary[1] * (vary[2] + 26 * k_1) - vary[0] * (vary[3] + 26 * k_2)) / (vary[1] - vary[0])); while(b < 0) { b = b + 26; } // b = b % 26; // a = a + 26; printf("k1=%dn",k_1); printf("k2=%dn",k_2); printf("密钥a = %dn", a); printf("密钥b = %dn", b); }
//多表代换密码 // YOUR PIN NO IS FOUR ONE TWO SIX // A = 11 2 19 5 23 25 20 7 17 // A^-1 = 10 23 7 15 9 22 5 9 21 // B = 0 0 0 // PLEASE SEND ME THE BOOK MY CREDIT CARD NO IS SIX ONE TWO ONE THREE EIGHT SIX ZERO ONE SIX EIGHT FOUR NINE SEVEN ZERO TWO // A = 3 13 21 9 15 10 6 25 10 17 4 8 1 23 7 2 // A^-1 = 23 13 20 5 0 10 11 26 9 11 15 22 9 22 6 25 // B = 1 21 8 17 #include#include #include #include #include #define SIZE 2 int GCD(int a); void fun(char *str); void Input_B(int B[]); void Iuput_A(int A[][SIZE]); int mod_invese(int d, int n); int getA(int arcs[SIZE][SIZE], int n); void A_NI_Mod(int ans[SIZE][SIZE], int det); void Change_To_Number(char *str, int StrLen); void solve_function(char encode[], char decode[]); void getAStart(int arcs[SIZE][SIZE], int n, int ans[SIZE][SIZE]); void Encrypt(int A[][SIZE], char Enstring[], int StrLen, int B[]); void Decrypt(int A_inverse[][SIZE], char Destring[], int StrLen, int B[]); int main(void) { int A[SIZE][SIZE]; int B[SIZE]; int astar[SIZE][SIZE]; int A_inverse[SIZE][SIZE]; printf("n******多表代换******n"); while (1) { printf("nn请输入功能序号:n0.加密n1.解密n2.矩阵密钥n3.求逆矩阵n4.退出程序n选择功能:"); int i = 0, j = 0, flag = 0; int DET; int StrLen; int function; char encode[100] = " "; char decode[100] = " "; char ch[1000] = " "; char solve[1000] = " "; scanf("%d", &function); fflush(stdin); switch (function) { case 0: printf("n请输入待加密明文(长度为%d的倍数):", SIZE); gets(ch); fun(ch); printf("n请输入加密密钥密钥(A,B)(分组为%d):nA:", SIZE); Iuput_A(A); // A的输入 printf("nB:"); Input_B(B); // B的输入 StrLen = strlen(ch); Encrypt(A, ch, StrLen, B); printf("n加密后的密文是:"); for (i = 0; i < StrLen; i++) { printf("%c", ch[i]); flag++; if (flag % SIZE == 0) printf(" "); } break; case 1: printf("n请输入待解密密文(长度为%d的倍数):", SIZE); gets(solve); fun(solve); printf("n请输入解密密钥A^-1 (分组为%d):n", SIZE); printf("nA^-1:"); Iuput_A(A_inverse); // A^-1的输入 printf("nB:"); Input_B(B); // B的输入 StrLen = strlen(solve); if (StrLen % SIZE != 0) //对长度不是4的倍数的明文的处理, { for (int i = 0; i < (StrLen % SIZE); i++) { solve[StrLen + i] = ' '; } StrLen = StrLen + SIZE - StrLen % SIZE; solve[StrLen] = 0; //字符串以0结尾 } Decrypt(A_inverse, solve, StrLen, B); printf("n解密后的明文是:"); for (i = 0; i < StrLen; i++) { printf("%c", solve[i]); flag++; if (flag % SIZE == 0) printf(" "); } break; case 2: printf("n请输入已知明文:n"); gets(encode); printf("n请输入已知密文:n"); gets(decode); solve_function(encode, decode); break; case 3: printf("n请输入矩阵A:"); Iuput_A(A); DET = getA(A, SIZE); printf("n矩阵A的值为:%dn", DET); getAStart(A, SIZE, astar); printf("n代数余子式A*为:n"); for (i = 0; i < SIZE; i++) { for (j = 0; j < SIZE; j++) { printf("%dt", astar[i][j]); } printf("n"); } printf("n矩阵逆为:n"); A_NI_Mod(astar, DET); break; case 4: return 0; break; default: printf("n请输入正确的功能编号!n"); break; } } } void Change_To_Number(char *str, int StrLen) //转换成ASCII码 { int i; for (int i = 0; i < StrLen; i++) { if (str[i] >= 'a' && str[i] <= 'z') str[i] -= 'a'; if (str[i] >= 'A' && str[i] <= 'Z') str[i] -= 'A'; // printf("str[%d]=%dt",i,str[i]); } } void Iuput_A(int A[][SIZE]) // A与A^-1的输入 { for (int i = 0; i < SIZE; i++) for (int j = 0; j < SIZE; j++) scanf("%d", &A[i][j]); } void Input_B(int B[]) // B输入 { for (int i = 0; i < SIZE; i++) scanf("%d", &B[i]); } void Encrypt(int A[][SIZE], char Enstring[], int StrLen, int B[]) //加密函数,参数为 A,要加密的明文,明文长度,B { int n; int M[StrLen / SIZE][SIZE]; memset(M, 0, sizeof(M)); Change_To_Number(Enstring, StrLen); //转换成ASCII码 for (int i = 0; i < StrLen / SIZE; i++) //求Ci { for (int j = 0; j < SIZE; j++) { for (n = 0; n < SIZE; n++) { M[i][j] = M[i][j] + Enstring[i * SIZE + n] * A[j][n]; } M[i][j] = (M[i][j] + B[j]) % 26; } } for (int i = 0; i < StrLen / SIZE; i++) //数字对应字母 { for (int j = 0; j < SIZE; j++) { if (M[i][j] < 0) M[i][j] = M[i][j] + 26; Enstring[i * SIZE + j] = M[i][j] + 'A'; } } } void Decrypt(int A_inverse[][SIZE], char Destring[], int StrLen, int B[]) //解密函数,参数为 A^-1,要解密的密文,密文长度,B { int n; int M[StrLen / SIZE][SIZE]; memset(M, 0, sizeof(M)); Change_To_Number(Destring, StrLen); //英文字母和十进制数对应 for (int i = 0; i < StrLen / SIZE; i++) { for (int j = 0; j < SIZE; j++) { Destring[i * SIZE + j] -= B[j]; } } for (int i = 0; i < StrLen / SIZE; i++) //求Mi { for (int j = 0; j < SIZE; j++) { for (n = 0; n < SIZE; n++) { M[i][j] = M[i][j] + Destring[i * SIZE + n] * A_inverse[j][n]; } // printf("nM[%d][%d]=%dt",i,j,M[i][j]); M[i][j] = M[i][j] % 26; // printf("nM[%d][%d]=%dt",i,j,M[i][j]); } } for (int i = 0; i < StrLen / SIZE; i++) //数字对应字母 { for (int j = 0; j < SIZE; j++) { if (M[i][j] < 0) M[i][j] = M[i][j] + 26; Destring[i * SIZE + j] = M[i][j] + 'A'; } } } void fun(char *str) //删除字符串中的空格 { char *str_c = str; int i, j = 0; for (i = 0; str[i] != ' '; i++) { if (str[i] != ' ') str_c[j++] = str[i]; } str_c[j] = ' '; str = str_c; } int getA(int arcs[SIZE][SIZE], int n) //按第一行展开计算|A| { if (n == 1) { return arcs[0][0]; } int ans = 0; int temp[SIZE][SIZE]; int i, j, k; for (i = 0; i < n; i++) { for (j = 0; j < n - 1; j++) { for (k = 0; k < n - 1; k++) { temp[j][k] = arcs[j + 1][(k >= i) ? k + 1 : k]; } } int t = getA(temp, n - 1); if (i % 2 == 0) { ans += arcs[0][i] * t; } else { ans -= arcs[0][i] * t; } } return ans; } void getAStart(int arcs[SIZE][SIZE], int n, int ans[SIZE][SIZE]) //计算每一行每一列的每个元素所对应的余子式,组成A* { if (n == 1) { ans[0][0] = 1; return; } int i, j, k, t; int temp[SIZE][SIZE]; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { for (k = 0; k < n - 1; k++) { for (t = 0; t < n - 1; t++) { temp[k][t] = arcs[k >= i ? k + 1 : k][t >= j ? t + 1 : t]; } } ans[j][i] = getA(temp, n - 1); if ((i + j) % 2 == 1) { ans[j][i] = -ans[j][i]; } } } } int mod_invese(int d, int n) //求d模n的逆,n 为正整数 { int a; //被除数 int b; //除数 int q; //商 int r; int u = 0; int v = 1; int t; a = n; b = (d >= 0) ? (d % n) : -(d % n); //规定正负数mod(n)都取正; while (b != 0) { q = (int)a / b; r = a - b * q; a = b; b = r; t = v; v = u - q * v; u = t; //把每次没有进行运算的v的值给u } //辗转相除,直到余数b=0,跳出循环 if (a != 1) return 0; return ((u < 0) ? u + n : u); //返回的值都是mod(n)后的值,使得最后的值是正数; } void A_NI_Mod(int ans[SIZE][SIZE], int det) //求A逆 { int i, j; int a_ni[SIZE][SIZE]; for (i = 0; i < SIZE; i++) { for (j = 0; j < SIZE; j++) { a_ni[i][j] = (mod_invese(det, 26) * ans[i][j]) % 26; if (a_ni[i][j] <= 0) { a_ni[i][j] += 26; } printf("%dt", a_ni[i][j]); } printf("n"); } } int GCD(int a) //判断互素 { int number = 26; int r = a % number; int flag = 0; while (r != 0) { a = number; number = r; r = a % number; } if (number != 1) { return flag; } else { return flag + 1; } } void solve_function(char M[], char C[]) //求解密钥 { int A[2][2]; int B[2] = {0, 0}; int i; int flag = 0; memset(A, 0, sizeof(A)); int A_deverse = 0; Change_To_Number(M, 4); Change_To_Number(C, 4); for (A[0][0] = 1; A[0][0] < 26; A[0][0]++) { for (A[0][1] = 1; A[0][1] < 26; A[0][1]++) { for (A[1][0] = 1; A[1][0] < 26; A[1][0]++) { for (A[1][1] = 1; A[1][1] < 26; A[1][1]++) { flag = 0; A_deverse = A[0][0] * A[1][1] - A[0][1] * A[1][0]; if (GCD(A_deverse) != 1) continue; if ((A[0][0] * M[0] + A[0][1] * M[1]) % 26 == C[0]) flag++; if ((A[0][0] * M[2] + A[0][1] * M[3]) % 26 == C[2]) flag++; if ((A[1][0] * M[0] + A[1][1] * M[1]) % 26 == C[1]) flag++; if ((A[1][0] * M[2] + A[1][1] * M[3]) % 26 == C[3]) flag++; if (flag == 4) { printf("n"); printf("矩阵A为:n"); printf("%dt%dn%dt%dn", A[0][0], A[0][1], A[1][0], A[1][1]); break; } } } } } }



