仿射加密加解密算法
概述:基本上和數學上的仿射變換類似
y=ax+b,通過如此達到一一對應加密。
仿射變換加密加密過程: 加密算法:c=a*m+ b(mod n) 加密過程: 1.獲取a,b(密鑰),n(字符個數) 2.獲取明文。 3.加密成密文,明文轉換成各個字符所對應的數字,將所得數字帶入上面的算法公式,得到數字再轉換成對應的字符 解密過程: 算法:m=a^-1(m-b)(mod n)這里a^-1不是指倒數,而是a關于字符數量模的乘法可逆元,下面介紹一下乘法可逆元 乘法可逆元定義;
群G中任意一個元素a,都在G中有唯一的逆元a‘,具有性質aa'=a'a=e,其中e為群的單位元 這個官方的定義不學數論什么肯定看不太懂。。沒事我們只研究數學應用,不學理論, 舉個例子好了: 4關于模7的乘法逆元為多少? 可令4X≡1mod7,即可等價于4X=7K+1,其中X,K為整數,求X和K。 由此看出可逆元的通俗定義 如果ax≡1modf,那么a為關于模f的乘法逆元。 另外也有條件,當a與f互素時,a關于模f的乘法逆元有解。如果不互素,則無解。如果f為素數,則從1到f-1的任意數都與f互素,即在1到f-1之間都恰好有一個關于模f的乘法逆元。 再來一個更具體的例子, 求5關于14的乘法逆元 用輾轉相除法 14=5*2+4 5=4*1+1 反過來寫 1=5-4=5-(14-5*2)=5*3-14 因此5關于模14的乘法逆元為3. 如此即可求出逆元,然后再帶入公式即可實現解密。 下面給出仿射加密算法的算法實現。(直觀起見采用C++)
#include<iostream> using namespace std; #define N 26 //這里只采用26個字母的加解密//加密 char *encry(char *Plain, int a, int b, int n); char *decry(char *Cipher, int a, int b, int n); //獲取可行仿射加密的a值數組 void setArr(int Canuse[], int n); //求GCD(最大公約數) int Gcd(int a, int b); //求a關于模n的乘法可逆元 int Multiplicative_inverse_modulo(int Canuse[], int a, int n); int main() {int a, b;char str[200] = "";cout << ("輸入密鑰a,b的值") << endl;cin >> a >> b;cout << "輸入明文內容" << endl;cin >> str;cout << "明文為" << endl;cout << str << endl;//加密encry(str, a, b, N);//輸出密文cout << str << endl;//解密decry(str, a, b, N);//輸出解密內容cout << str << endl;return 0; } //加密函數實現 char *encry(char *Plain, int a, int b, int n) {char *tmp = Plain;if (Plain == NULL)return NULL;while (*Plain) {if (' ' == *Plain){++Plain;continue;}if ((*Plain < 'A') || (*Plain > 'Z'))return NULL;*Plain -= 'A';*Plain = (a*(*Plain) + b) % n;*Plain += 'A';++Plain;}return tmp; } //解密所需基礎算法實現 void setArr(int Canuse[], int n) {for (int i = 1; i < n; i++) {if (1 == Gcd(n, i))*(Canuse++) = i;} } int Gcd(int a, int b) {int gcd = 0;int div = 0;//輾轉相除法do {div = a%b;gcd = b;a = b;b = div;} while (div);return gcd; } //求乘法可逆元 int Multiplicative_inverse_modulo(int Canuse[], int a, int n) {for (int i = 0; Canuse[i] != 0; i++) {if (1 == (a*Canuse[i]) % n)return Canuse[i];}return 0; } //解密實現 char *decry(char *Cipher, int a, int b, int n) {char *tmp = Cipher;int Canuse[32] = { 0 };//符合條件的a值int moda = 0;//a的乘法可逆元int i = 0;if (Cipher == NULL)return NULL;for (; i < 32; i++)Canuse[i] = 0;setArr(Canuse, n);//存放符合條件的a.moda = Multiplicative_inverse_modulo(Canuse, a, n);while (*Cipher) {if (' ' == *Cipher) {++Cipher;continue;}if ((*Cipher < 'A') || (*Cipher > 'Z'))return NULL;*Cipher -= 'A';*Cipher = (moda*(*Cipher - b + n)) % n;*Cipher += 'A';++Cipher;}return tmp; }只恨數學學的不夠多啊。
仿射變換加密加密過程: 加密算法:c=a*m+ b(mod n) 加密過程: 1.獲取a,b(密鑰),n(字符個數) 2.獲取明文。 3.加密成密文,明文轉換成各個字符所對應的數字,將所得數字帶入上面的算法公式,得到數字再轉換成對應的字符 解密過程: 算法:m=a^-1(m-b)(mod n)這里a^-1不是指倒數,而是a關于字符數量模的乘法可逆元,下面介紹一下乘法可逆元 乘法可逆元定義;
群G中任意一個元素a,都在G中有唯一的逆元a‘,具有性質aa'=a'a=e,其中e為群的單位元 這個官方的定義不學數論什么肯定看不太懂。。沒事我們只研究數學應用,不學理論, 舉個例子好了: 4關于模7的乘法逆元為多少? 可令4X≡1mod7,即可等價于4X=7K+1,其中X,K為整數,求X和K。 由此看出可逆元的通俗定義 如果ax≡1modf,那么a為關于模f的乘法逆元。 另外也有條件,當a與f互素時,a關于模f的乘法逆元有解。如果不互素,則無解。如果f為素數,則從1到f-1的任意數都與f互素,即在1到f-1之間都恰好有一個關于模f的乘法逆元。 再來一個更具體的例子, 求5關于14的乘法逆元 用輾轉相除法 14=5*2+4 5=4*1+1 反過來寫 1=5-4=5-(14-5*2)=5*3-14 因此5關于模14的乘法逆元為3. 如此即可求出逆元,然后再帶入公式即可實現解密。 下面給出仿射加密算法的算法實現。(直觀起見采用C++)
#include<iostream> using namespace std; #define N 26 //這里只采用26個字母的加解密//加密 char *encry(char *Plain, int a, int b, int n); char *decry(char *Cipher, int a, int b, int n); //獲取可行仿射加密的a值數組 void setArr(int Canuse[], int n); //求GCD(最大公約數) int Gcd(int a, int b); //求a關于模n的乘法可逆元 int Multiplicative_inverse_modulo(int Canuse[], int a, int n); int main() {int a, b;char str[200] = "";cout << ("輸入密鑰a,b的值") << endl;cin >> a >> b;cout << "輸入明文內容" << endl;cin >> str;cout << "明文為" << endl;cout << str << endl;//加密encry(str, a, b, N);//輸出密文cout << str << endl;//解密decry(str, a, b, N);//輸出解密內容cout << str << endl;return 0; } //加密函數實現 char *encry(char *Plain, int a, int b, int n) {char *tmp = Plain;if (Plain == NULL)return NULL;while (*Plain) {if (' ' == *Plain){++Plain;continue;}if ((*Plain < 'A') || (*Plain > 'Z'))return NULL;*Plain -= 'A';*Plain = (a*(*Plain) + b) % n;*Plain += 'A';++Plain;}return tmp; } //解密所需基礎算法實現 void setArr(int Canuse[], int n) {for (int i = 1; i < n; i++) {if (1 == Gcd(n, i))*(Canuse++) = i;} } int Gcd(int a, int b) {int gcd = 0;int div = 0;//輾轉相除法do {div = a%b;gcd = b;a = b;b = div;} while (div);return gcd; } //求乘法可逆元 int Multiplicative_inverse_modulo(int Canuse[], int a, int n) {for (int i = 0; Canuse[i] != 0; i++) {if (1 == (a*Canuse[i]) % n)return Canuse[i];}return 0; } //解密實現 char *decry(char *Cipher, int a, int b, int n) {char *tmp = Cipher;int Canuse[32] = { 0 };//符合條件的a值int moda = 0;//a的乘法可逆元int i = 0;if (Cipher == NULL)return NULL;for (; i < 32; i++)Canuse[i] = 0;setArr(Canuse, n);//存放符合條件的a.moda = Multiplicative_inverse_modulo(Canuse, a, n);while (*Cipher) {if (' ' == *Cipher) {++Cipher;continue;}if ((*Cipher < 'A') || (*Cipher > 'Z'))return NULL;*Cipher -= 'A';*Cipher = (moda*(*Cipher - b + n)) % n;*Cipher += 'A';++Cipher;}return tmp; }只恨數學學的不夠多啊。
總結
- 上一篇: android监控io产生的应用,And
- 下一篇: 微信小程序万里目_微信小程序“注册”你不