维吉尼亚密码:
加密:
void EnVirginia(char* plaintext, int* k)
{
int length = strlen(plaintext);
int m, n;
for (int i = 0; i < length; i++)
{
m = plaintext[i] - 'a';
n = m + k[i];
n < 26 ? n = n : n = n % 26;
printf("%c", 'a' + n);
}
printf("\n");
}
解密:
void DeVirginia(char* ciphertext, int* k)
{
int length = strlen(ciphertext);
int m, n;
for (int i = 0; i < length; i++)
{
m = ciphertext[i] - 'a';
n = m - k[i];
n >= 0 ? n = n : n = n + 26;
printf("%c", 'a' + n);
}
printf("\n");
}
希尔密码:
加密:
void EnHillCipher(char* plaintext, int k[][10])
{
int length = strlen(plaintext);
int x[100];
int y[4][4];
for (int i = 0; i <=length; i++)
{
x[i+1] = plaintext[i] - 'a';
}
for(int i=1;i<=3;i++)
for (int j = 1; j <= 3; j++)
{
y[i][j] = x[(i-1) * 3 + j];
}
int matrix[100] = { 0 };
int count = 1;
int flag=1;
while (count <=length)
{
for (int i = 0; i <3; i++)
{
for (int j = 0; j<3; j++)
{
matrix[count] = k[i][j] * y[flag][j+1] + matrix[count];
}
matrix[count] = matrix[count] % 26;
count++;
}
flag++;
}
for (int j = 1; j <length; j++)
{
printf("%c", 'a' + matrix[j]);
}
printf("\n");
}
解密:
void DeHillcipher(char* ciphertext, int k[][10])
{
int length = strlen(ciphertext);
int x[100];
int y[4][4];
for (int i = 0; i <= length; i++)
{
x[i + 1] = ciphertext[i] - 'a';
}
for (int i = 1; i <= 3; i++)
for (int j = 1; j <= 3; j++)
{
y[i][j] = x[(i - 1) * 3 + j];
}
int matrix[100] = { 0 };
int count = 1;
int flag = 1;
while (count <= length)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
matrix[count] = k[i][j] * y[flag][j + 1] + matrix[count];
}
matrix[count] = matrix[count] % 26;
count++;
}
flag++;
}
for (int j = 1; j < length; j++)
{
printf("%c", 'a' + matrix[j]);
}
printf("\n");
}
希尔密码的加解密算法其实是一样的,只不过密钥不同,解密的密钥是加密密钥的乘法逆元。同时密钥的长度也可以自行调整,最好密钥所选矩阵的行数和列数等于明文的长度,上面算法使用的是3*3矩阵,我是用来加密长度为8的明文,可以在明文后加任意字符,最后输出八个即可。
因为时间有限后续生成8*8,或更高维的n阶方阵的算法,会后面慢慢学习上传。