You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言Affine Cipher代码问题:小写字母加解密失败求助

仿射密码小写字母加解密失败的问题排查与修复

问题根源分析

你的代码对大小写字母的加解密逻辑均存在错误,大写字母因ASCII值的巧合(如'A'=65,65%26=13)暂时表现正常,但小写字母的ASCII值(97-122)直接参与计算会完全偏离仿射密码的0-25数字范围,导致加解密失效。具体问题如下:

  • 加解密未做0-25映射:仿射密码核心公式基于0-25的数字(对应A-Z或a-z),但你直接使用字母的原始ASCII值计算,结果完全超出有效范围。
  • GCD函数递归返回缺失:递归分支未返回计算结果,会导致最大公约数计算错误,进而影响模逆元的正确性。

修复后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX_LENGTH 100 

int GCD(int a, int b) {
    if(b == 0) {
        return a;
    }
    return 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 >= 'A' && temp_1 <= 'Z') {
            // 先映射到0-25范围,再应用加密公式
            temp_2 = (a * (temp_1 - 'A') + b) % 26;
            temp_2 = temp_2 < 0 ? temp_2 + 26 : temp_2; // 处理负数模结果
            Ciphertext[i++] = 'A' + temp_2;
        }else if(temp_1 >= 'a' && temp_1 <= 'z') {
            // 小写字母同理映射
            temp_2 = (a * (temp_1 - 'a') + b) % 26;
            temp_2 = temp_2 < 0 ? temp_2 + 26 : temp_2;
            Ciphertext[i++] = 'a' + temp_2;
        } else if(temp_1 == ' ') {
            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 += 26;
    }

    int temp_1, temp_2, i;
    i = 0;

    while(Ciphertext[i] != '\0') {
        temp_1 = Ciphertext[i];

        if(temp_1 >= 'A' && temp_1 <= 'Z') {
            // 转0-25范围后应用解密公式:(x - b) * a^{-1} mod 26
            temp_2 = ((temp_1 - 'A' - b + 26) * temp_a_inverse) % 26;
            temp_2 = temp_2 < 0 ? temp_2 + 26 : temp_2;
            Decrypted_Plaintext[i++] = 'A' + temp_2;
        } else if(temp_1 >= 'a' && temp_1 <= 'z') {
            // 小写字母同理处理
            temp_2 = ((temp_1 - 'a' - b + 26) * temp_a_inverse) % 26;
            temp_2 = temp_2 < 0 ? temp_2 + 26 : temp_2;
            Decrypted_Plaintext[i++] = 'a' + temp_2;
        } else if(temp_1 == ' ') {
            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);
    Decryption(Ciphertext, Decrypted_Plaintext, a, b);
    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;
}

关键修复说明

  1. GCD函数:补全递归调用的返回值,确保最大公约数计算正确,这是模逆元存在的核心前提。
  2. 加密逻辑:对大小写字母分别减去'A'或'a',转换为0-25的数字后再应用仿射加密公式(a*x + b) mod 26,最后映射回对应ASCII字母。
  3. 解密逻辑:先将密文字母转换为0-25的数字,使用解密公式((x - b) * a^{-1}) mod 26(加26避免负数),再转换回对应ASCII字母。

内容的提问来源于stack exchange,提问作者Omen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 09:07:32