C语言实现仿射密码体制
算法思想:
1、通過用戶輸入的加密函數(shù)的斜率和截距(a與b),可以利用a計算出a的逆源。在輸入a之后,要判斷a與26是否互素(即a值與26的最大公約數(shù)為1),代碼中采用輾轉(zhuǎn)相除法,如果不符合要求,請?zhí)崾局匦螺斎搿G蠼鈇的逆源:例如7的逆源是15。原因是(7*15)%26=1,這里的26代表字母表26個字母。假設(shè)我們當前不知道7的逆源是15。我們可以設(shè)為X,于是變?yōu)?#xff08;7*X)%26=1,所以可以假設(shè)7*X=27或者等于27+i*26,此時如果想把X解出來,可以用c=27/7或者c=(27+i*26)/7,存儲在變量c中。求出a的逆源c后,c即為解密函數(shù)的系數(shù),可以利用c與b求出解密函數(shù)的截距。數(shù)學表達式如下:d=(c*b)%26。代碼書寫如下(逆源存儲到變量c中,最多加999個26)。
for (int i = 0; i < 1000; i++){if ((27 + 26 * i) % a == 0) {c = (27 + 26 * i) / a;break;}} d = (c * b) % 26;2、定義一個數(shù)組alphabet存儲26字母。將用戶輸入的明文或者密文轉(zhuǎn)換為數(shù)字。方法是查找alphabet數(shù)組,看字母所在下標是多少,比如A對應(yīng)下標是0,B對應(yīng)的是1等等。將這些數(shù)字用另外一個數(shù)組str_num存儲起來。然后進行加密解密計算。加密:用str_num[i]=(a*str_num[i]+b+26)%26;在%26之前還加上了26是為了保證所得的數(shù)是正數(shù)。這就已經(jīng)是加密過的,不過還得將這些數(shù)字對應(yīng)字母表查找對應(yīng)的字母,找到的對應(yīng)字母就是最終的密文結(jié)果。解密過程類似:str_num[i] = ((c * str_num[i] - d)+26) % 26;
3、全部代碼:
#define _CRT_SECURE_NO_WARNINGS 1 //仿射密碼體制#include<stdio.h>//菜單打印 void menu() {printf("------ 仿射密碼體制 --------\n");printf("------- 1. 加密 --------\n");printf("------- 2. 解密 --------\n");printf("------- 0. 退出 --------\n"); }void encryption_and_decryption(int input) {char alphabet[26] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};int count = 0;char str[100] = { 0 };//最長加密解密長度為100int str_num[100] = { 0 };//用于存儲字母在字母表中的下標int a = 0, b = 0, c = 0, d = 0;printf("請輸入加密函數(shù)的a,b值(空格隔開):");scanf_s("%d %d", &a, &b);int temp = 0;//用e存儲26,判斷輸入的a值是否與26互素(采用輾轉(zhuǎn)相除法)while (e != 0) {temp = a % 26;a = e;e = temp;}//如果a不是與26互素,提示用戶重新輸入a值if (a != 1) {printf("輸入的a值和26不是互素的,請重新輸入a值:");scanf_s("%d", &a);}for (int i = 0; i < 1000; i++){if ((27 + 26 * i) % a == 0) {c = (27 + 26 * i) / a;break;}}d = (c * b) % 26;if (input == 1) { //執(zhí)行加密算法printf("請輸入明文(中間不要有空格):");}else //執(zhí)行解密算法{printf("請輸入密文(中間不要有空格):");}getchar(); //吸收回車for (int i = 0; i < 100; i++) {scanf_s("%c", &str[i]);count++;if (str[i] == '\n') { //回車代表輸入結(jié)束count--;break;}}for (int i = 0; i < count; i++){if (str[i] >= 'a' && str[i] <= 'z') { //將小寫轉(zhuǎn)換為大寫str[i] -= 32;}}for (int i = 0; i < count; i++){for (int j = 0; j < 26; j++){if (str[i] == alphabet[j]) {str_num[i] = j;break;}}}if (input == 1) {//加密算法for (int i = 0; i < count; i++){str_num[i] = ((a * str_num[i] + b)+26) % 26;}}else{//解密算法for (int i = 0; i < count; i++){str_num[i] = ((c * str_num[i] - d)+26) % 26;}}for (int i = 0; i < count; i++){for (int j = 0; j < 26; j++){if (str_num[i] == j) {str[i] = alphabet[j];}}}if (input == 1) {printf("生成密文是:");}else {printf("解密明文是:");}for (int i = 0; i < count; i++){printf("%c", str[i]);}printf("\n"); }void test() {int input = 0;do {menu();printf("請選擇:->");scanf_s("%d", &input);switch (input){case 1:encryption_and_decryption(input);break;case 2:encryption_and_decryption(input);break;case 0:printf("已退出加密解密系統(tǒng)\n");break;default:printf("輸入有誤,請重新輸入!\n");break;}} while (input); }int main() {test();return 0; }4、運行結(jié)果截圖:
?上述運行中第一次輸入的a值為14,14和26的最大公約數(shù)是2,不是1,因此提示用戶重新輸入。
如果內(nèi)容對你有幫助,關(guān)注我,給我點個小小的贊吧!
若內(nèi)容有誤,請指正并多多包容,謝謝。
總結(jié)
以上是生活随笔為你收集整理的C语言实现仿射密码体制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 西门子PLC-smart二分频源程序带解
- 下一篇: Nginx 安装部署以及负载均衡