#include <stdio.h>
#include <stdlib.h>
#include <time.h>
# define MAX_LENGTH 100
int GCD(int a, int b) {
if(b == 0) {
return a;
}
GCD(b, a%b);
}
struct Pair{
int x, y;
};
struct Pair Extended_Euclidean_Algorithm(int a, int b) {
if(b == 0) {
struct Pair answer;
answer.x = 1;
answer.y = 0;
return answer;
}
struct Pair small_answer = Extended_Euclidean_Algorithm(b, a%b);
struct Pair answer;
answer.x = small_answer.y;
answer.y = small_answer.x - (a/b)*small_answer.y;
return answer;
}
void Encryption(char Plaintext[], char Ciphertext[], int a, int b) {
int temp_1, temp_2, i;
i = 0;
while(Plaintext[i] != '\0') {
temp_1 = Plaintext[i];
if(temp_1 >= 65 && temp_1 <= 90) {
temp_2 = (a*temp_1 + b)%26;
Ciphertext[i++] = 'A' + temp_2;
}else if(temp_1 >= 97 && temp_1 <= 122) {
temp_2 = (a*temp_1 + b)%26;
Ciphertext[i++] = 'a' + temp_2;
} else if(temp_1 == 32) {
Ciphertext[i++] = ' ';
}
}
Ciphertext[i] = '\0';
}
void Decryption(char Ciphertext[], char Decrypted_Plaintext[], int a, int b) {
struct Pair inverse;
int temp_a_inverse;
inverse = Extended_Euclidean_Algorithm(26, a);
temp_a_inverse = inverse.y;
if(temp_a_inverse < 0) {
temp_a_inverse = temp_a_inverse + 26;
}
int temp_1, temp_2, i;
i = 0;
while(Ciphertext[i] != '\0') {
temp_1 = Ciphertext[i];
if(temp_1 >= 65 && temp_1 <= 90) {
temp_2 = ((temp_1 + 26 - b)*temp_a_inverse)%26;
Decrypted_Plaintext[i++] = 'A' + temp_2;
} else if(temp_1 >= 97 && temp_1 <= 122) {
temp_2 = ((temp_1 + 26 - b)*temp_a_inverse)%26;
Decrypted_Plaintext[i++] = 'a' + temp_2;
} else if(temp_1 == 32) {
Decrypted_Plaintext[i++] = ' ';
}
}
Decrypted_Plaintext[i] = '\0';
}
int main() {
char Plaintext[MAX_LENGTH], Ciphertext[MAX_LENGTH], Decrypted_Plaintext[MAX_LENGTH];
char c;
printf("Enter the plaintext: ");
int i = 0;
while((c = getchar()) != '\n') {
Plaintext[i] = c;
i++;
}
Plaintext[i] = '\0';
printf("Choose any number from the given numbers: ");
int a, b, temp_a;
for(int j = 1; j <= 26; j++) {
temp_a = GCD(26, j);
if(temp_a == 1){
printf("%d |", j);
}
}
printf("\n");
scanf("%d", &a);
srand(time(0));
b = (rand()%(26)) + 1;
Encryption(Plaintext, Ciphertext, a, b); //Encrypting Plaintext
Decryption(Ciphertext, Decrypted_Plaintext, a, b); //Decrypting Ciphertext
printf("The Plaintext is: %s\n", Plaintext);
printf("a = %d || b = %d\n", a, b);
printf("The Ciphertext is: %s\n", Ciphertext);
printf("The Decrypted Plaintext is: %s\n", Decrypted_Plaintext);
return 0;
}
我已经用C编写了仿射密码的代码。它正确地加密/解密了大写字母,但错误地加密/解密了小写字母所以,当我测试它的大写字母时,它工作正常,但是当我尝试测试它的小写字母时每次都会失败。那么,谁能告诉我哪里出错了。
使用大写单词和小写单词尝试代码会导致小写单词出现不良行为。
craig@Vera:~/C_Programs/Console/Decipher/bin/Release$ ./Decipher
Enter the plaintext: HELLO
Choose any number from the given numbers: 1 |3 |5 |7 |9 |11 |15 |17 |19 |21 |23 |25 |
3
The Plaintext is: HELLO
a = 3 || b = 12
The Ciphertext is: ULGGP
The Decrypted Plaintext is: HELLO
craig@Vera:~/C_Programs/Console/Decipher/bin/Release$ ./Decipher
Enter the plaintext: Hello
Choose any number from the given numbers: 1 |3 |5 |7 |9 |11 |15 |17 |19 |21 |23 |25 |
3
The Plaintext is: Hello
a = 3 || b = 14
The Ciphertext is: Wfaaj
The Decrypted Plaintext is: Hmttw
即使在进行一些简单的调试时,我也无法用小写字符来确定确切的行为问题,除了在小写 if/else 块中进行的“temp_2”计算乘法/计算似乎存在问题。加密和解密。
由于最终结果是一次选择一个字符并对该字符应用加密/偏移量计算,因此最简单的解决方案是始终将该字符视为大写字符,执行加密或解密,然后计算其偏移量小写字符“a”而不是大写字符“A”。
以下是展示重构步骤的代码块。
首先,根据好评,“最大公约数”函数被更正为从函数的递归调用中返回一个整数。
int GCD(int a, int b)
{
if(b == 0)
{
return a;
}
return GCD(b, a%b); /* Refactored per good comments */
}
然后重构加密和解密函数中的公式,将字符处理为大写值,然后添加“字符'a'”偏移量。
void Encryption(char Plaintext[], char Ciphertext[], int a, int b)
{
int temp_1, temp_2, i;
i = 0;
while(Plaintext[i] != '\0')
{
temp_1 = Plaintext[i];
if(temp_1 >= 65 && temp_1 <= 90)
{
temp_2 = (a*temp_1 + b)%26;
Ciphertext[i++] = 'A' + temp_2;
}
else if(temp_1 >= 97 && temp_1 <= 122)
{
temp_2 = (a*(temp_1 - 32) + b) % 26; /* Refactored to treat character as uppercase */
Ciphertext[i++] = 'a' + temp_2; /* Offset value is applied to lowercase reference */
}
else if(temp_1 == 32)
{
Ciphertext[i++] = ' ';
}
}
Ciphertext[i] = '\0';
}
void Decryption(char Ciphertext[], char Decrypted_Plaintext[], int a, int b)
{
struct Pair inverse;
int temp_a_inverse;
inverse = Extended_Euclidean_Algorithm(26, a);
temp_a_inverse = inverse.y;
if(temp_a_inverse < 0)
{
temp_a_inverse = temp_a_inverse + 26;
}
int temp_1, temp_2, i;
i = 0;
while(Ciphertext[i] != '\0')
{
temp_1 = Ciphertext[i];
if(temp_1 >= 65 && temp_1 <= 90)
{
temp_2 = ((temp_1 + 26 - b)*temp_a_inverse)%26;
Decrypted_Plaintext[i++] = 'A' + temp_2;
}
else if(temp_1 >= 97 && temp_1 <= 122)
{
temp_2 = ((temp_1 - 32 + 26 - b)*temp_a_inverse)%26; /* Refactored to treat character as uppercase */
Decrypted_Plaintext[i++] = 'a' + temp_2; /* Offset value is applied to lowercase reference */
}
else if(temp_1 == 32)
{
Decrypted_Plaintext[i++] = ' ';
}
}
Decrypted_Plaintext[i] = '\0';
}
以下是一些测试,显示了此重构后的终端输出。
craig@Vera:~/C_Programs/Console/Decipher/bin/Release$ ./Decipher
Enter the plaintext: Hello
Choose any number from the given numbers: 1 |3 |5 |7 |9 |11 |15 |17 |19 |21 |23 |25 |
3
The Plaintext is: Hello
a = 3 || b = 14
The Ciphertext is: Wniir
The Decrypted Plaintext is: Hello
craig@Vera:~/C_Programs/Console/Decipher/bin/Release$ ./Decipher
Enter the plaintext: Welcome home
Choose any number from the given numbers: 1 |3 |5 |7 |9 |11 |15 |17 |19 |21 |23 |25 |
7
The Plaintext is: Welcome home
a = 7 || b = 21
The Ciphertext is: Gkhwcok fcok
The Decrypted Plaintext is: Welcome home
这可能不是像希望的那样优雅的解决方案,但它确实提供了一个简化的解决方案,通过后退一步来确定可以简化问题的地方。
从中得到的收获可能是深入研究一些“C”教程,因为它们与字符数组、加密方法和 ASCII 字符集有关。