シミュレーション暗号化復号アルゴリズム

3231 ワード

概要:基本的に数学的なシミュレーション変換と似ています
y=ax+bであり、これにより1つ1つの対応暗号化に達する.
シミュレーション変換暗号化プロセス:
暗号化アルゴリズム: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の乗算逆元はいくらですか?
4 X≡1 mod 7にすることができて、4 X=7 K+1に等価で、その中のX、Kは整数で、XとKを求めます.
このことから可逆元の通俗的な定義がわかる
ax≡1 modfの場合、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
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;
}
数学が足りないのが嫌いですね.