【資訊保安概論】實驗一
阿新 • • 發佈:2018-11-22
實驗一 古典密碼
- 實驗目的
熟悉古典加密演算法,能夠程式設計實現各種常見的加密演算法。
二、實驗任務
1.程式設計實現歐幾里得演算法求最大公因子;
2.程式設計實現凱撒(Caesar)密碼;
3.程式設計實現仿射密碼、和Hill密碼
三、部分參考答案
編寫實現古典密碼的程式,能對給定的明文或密文進行正確的加密和解密。
(1) 仿射密碼
引數選取:模數n=26+10=36,k2為學號後2位;k1為與學號後2位最近的素數。
加解密:加密自己名字的全拼和學號,再解密。
加密程式碼:
#include <iostream> #include <stdlib.h> #include <string> using namespace std; int main() { /* (1) 仿射密碼 引數選取:模數n=26+10=36,k2為學號後2位;k1為與學號後2位最近的素數。 加解密:加密自己名字的全拼和學號,再解密。 */ int n = 36; string m, c; int buff[32], len = 0, k1 = 0, k2 = 0; cout << "輸入明文:" << endl; cin >> m; cout << "輸入k1:"; cin >> k1; cout << "輸入k2:"; cin >> k2; //把明文轉化成10進位制整數,0-9,a-z分別代表十進位制0-36 for (int i = 0; m[i] != '\0'; i++) { //字母轉10進位制整數 if (m[i] > '9') buff[i] = m[i] - 87; else buff[i] = m[i] - 48;//0ASCII為48 len++; } //加密運算,C=k1*m+k2 mod n; for (int i = 0; i < len; i++) { buff[i] = (buff[i] * k1 + k2) % n; } //把數字對應為密文空間內的字元 for (int i = 0; i < len; i++) { if (buff[i] < 10) m[i] = buff[i] + 48; else m[i] = buff[i] + 87; } cout << "密文為:" << endl; for (int i = 0; i<len; i++) { cout << m[i]; } cout << endl; //解密,M=(C-k2)*k1^(-1) system("pause"); return 0; }
解密程式碼:
#include <iostream> #include <stdlib.h> #include <string> using namespace std; //求解x^(-1)mod p int GetIne(int x, int p) { for (int i = 0; i<p; i++) { if (x*i%p == 1) { x = i; break; } } return x; } int main() { /* (1) 仿射密碼 引數選取:模數n=26+10=36,k2為學號後2位;k1為與學號後2位最近的素數。 加解密:加密自己名字的全拼和學號,再解密。 */ int n = 36; string m, c; int buff[32], len = 0, k1 = 0, k2 = 0, k = 0; cout << "輸入密文:" << endl; cin >> m; cout << "輸入k1:"; cin >> k1; cout << "輸入k2:"; cin >> k2; //把明文轉化成10進位制整數,0-9,a-z分別代表十進位制0-36 //解密,M=(C-k2)*k1^(-1) for (int i = 0; m[i] != '\0'; i++) { //字母轉10進位制整數 if (m[i] > '9') buff[i] = m[i] - 87; else buff[i] = m[i] - 48;//0ASCII為48 len++; } //解密運算,M=(C-k2)*k1^(-1) k = GetIne(k1, n); for (int i = 0; i < len; i++) { buff[i] = ((buff[i] - k2)*k) % n; if (buff[i] < 0) buff[i] += n; //buff[i] = (buff[i] * k1 + k2) % n; } //把數字對應為明文空間內的字元 for (int i = 0; i < len; i++) { if (buff[i] < 10) m[i] = buff[i] + 48; else m[i] = buff[i] + 87; } cout << "明文為:" << endl; for (int i = 0; i<len; i++) { cout << m[i]; } cout << endl; system("pause"); return 0; }
(2) 置換密碼
引數選取:分組長度為7;置換關係隨機選取;
加解密:加密自己名字的全拼和學號(長度不足時後面全補填充長度),再解密。
/*置換密碼
引數選取:分組長度為7;置換關係隨機選取;
加解密:加密自己名字的全拼和學號(長度不足時後面全補
填充長度),再解密。
string中的函式:
swap()--交換字元
push_back() --插入字元
*/
加密程式碼:
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
string m;
system("title = 加密");
cout << "輸入明文:" << endl;
cin >> m;
//cout << "string長度:" << m.size()<<endl;
////遍歷明文
//for (int i=0;m[i]!='\0';i++)
//{
// cout << m[i];
//}
//cout << endl;
//如果明文不足7的倍數就填字元A
for (int i = m.size(); i % 7 != 0; i++)
{
m.push_back('A'); //在字串後面插入字元A
}
//cout << "string長度:" << m.size() << endl;
////遍歷
//for (int i = 0;i<m.size(); i++)
//{
// cout << m[i];
//}
//加密
for (int i = 0; i < m.size(); i += 7)
{
swap(m[i], m[i + 2]);//f(1)
swap(m[i], m[i + 6]);//f(2)
swap(m[i], m[i + 3]);//f(3)
swap(m[i], m[i + 0]);//f(4)
swap(m[i], m[i + 5]);//f(5)
swap(m[i], m[i + 1]);//f(6)
swap(m[i], m[i + 4]);//f(7)
}
//輸出密文
cout << "密文為:" << endl;
for (int i = 0; i<m.size(); i++)
{
if (i != 0 && i % 7 == 0)
cout << endl;
cout << m[i];
}
cout << endl;
system("pause");
return 0;
}
2./*置換密碼
引數選取:分組長度為7;置換關係隨機選取;
加解密:加密自己名字的全拼和學號(長度不足時後面全補
填充長度),再解密。
string中的函式:
swap()交換字元
push_back()插入字元
*/
解密程式碼:
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
string m;
cout << "輸入密文:" << endl;
cin >> m;
system("title = 解密");
//cout << "string長度:" << m.size()<<endl;
////遍歷明文
//for (int i=0;m[i]!='\0';i++)
//{
// cout << m[i];
//}
//cout << endl;
//cout << "string長度:" << m.size() << endl;
////遍歷
//for (int i = 0;i<m.size(); i++)
//{
// cout << m[i];
//}
//解密
for (int i = 0; i < m.size(); i += 7)
{
swap(m[i], m[i + 4]);//f(7)
swap(m[i], m[i + 1]);//f(6)
swap(m[i], m[i + 5]);//f(5)
swap(m[i], m[i + 0]);//f(4)
swap(m[i], m[i + 3]);//f(3)
swap(m[i], m[i + 6]);//f(2)
swap(m[i], m[i + 2]);//f(1)
}
//輸出明文
cout << "明文為:" << endl;
for (int i = 0;m[i] != 'A'; i++)
{
/*if (i != 0 && i % 7 == 0)
cout << endl;*/
cout << m[i];
}
cout << endl;
system("pause");
return 0;
}
(3) Hill密碼
加密程式碼:
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
string m;
int buffer[4];
int a[4];//存放m*A mod 26的結果
int b[16];//存放m和A的轉置矩陣的乘積
//矩陣A的轉置矩陣
int A[] = { 8,6,5,10,
6,9,8,6,
9,5,4,11,
5,10,9,4 };
////A的逆矩陣的轉置矩陣
//int B[] = { 23,2,2,25,
// 20,11,20,2,
// 5,18,6,22,
// 1,1,25,25 };
cout << "輸入明文:" << endl;
cin >> m;
system("title = 加密");
//把字元轉化成10進位制整數
for (int i = 0; m[i] != '\0'; i++)
{
buffer[i] = m[i] - 97;
}
cout << "buffer陣列中的元素:" << endl;
for (int i = 0; i<4; i++)
{
cout << buffer[i] << ",";
}
cout << endl;
//加密C = m * A mod 26,把結果放入陣列a
for (int i = 0; i<16; i++)
{
b[i] = buffer[i % 4] * A[i];
}
cout << "b陣列中的元素:" << endl;
for (int i = 0; i<16; i++)
{
cout << b[i] << ",";
}
cout << endl;
for (int i = 0; i < 16; i += 4)
{
a[i / 4] = (b[i] + b[i + 1] + b[i + 2] + b[i + 3]) % 26;
if (a[i / 4] < 0)
a[i / 4] += 26;
}
cout << "a陣列中的元素:" << endl;
for (int i = 0; i<4; i++)
{
cout << a[i] << ",";
}
cout << endl;
//轉換為字元
cout << "密文為:" << endl;
for (int i = 0; i<4; i++)
{
m[i] = a[i] + 97;
cout << m[i];
}
cout << endl;
system("pause");
return 0;
}
解密程式碼:
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
int main()
{
string m;
int buffer[4];
int a[4];
int b[16];//存放m和A的轉置矩陣的乘積
//矩陣A的轉置矩陣
/*int A[] = { 8,6,5,10,
6,9,8,6,
9,5,4,11,
5,10,9,4 };*/
//A的逆矩陣的轉置矩陣
int B[] = { 23,2,2,25,
20,11,20,2,
5,18,6,22,
1,1,25,25 };
cout << "輸入密文:" << endl;
cin >> m;
system("title = 解密");
//把字元轉化成10進位制整數
for (int i = 0; m[i] != '\0'; i++)
{
buffer[i] = m[i] - 97;
}
cout << "buffer陣列中的元素:" << endl;
for (int i = 0; i<4; i++)
{
cout << buffer[i] << ",";
}
cout << endl;
//解密M = C * B mod 26,把結果放入陣列a,B是A的逆矩陣
for (int i = 0; i<16; i++)
{
b[i] = buffer[i % 4] * B[i];
}
cout << "b陣列中的元素:" << endl;
for (int i = 0; i<16; i++)
{
cout << b[i] << ",";
}
cout << endl;
for (int i = 0; i < 16; i += 4)
{
a[i / 4] = (b[i] + b[i + 1] + b[i + 2] + b[i + 3]) % 26;
if (a[i / 4] < 0)
a[i / 4] += 26;
}
cout << "a陣列中的元素:" << endl;
for (int i = 0; i<4; i++)
{
cout << a[i] << ",";
}
cout << endl;
//轉換為字元
cout << "明文為:" << endl;
for (int i = 0; i<4; i++)
{
m[i] = a[i] + 97;
cout << m[i];
}
cout << endl;
system("pause");
return 0;
}