简体   繁体   English

C中的仿射密码无法正常工作

[英]Affine Cipher in C doesn't work correctly

Disclaimer: Whatever is below, it's related to Affine Cipher. 免责声明:无论以下内容如何,​​都与Affine Cipher有关。 For whomever doesn't know it, it's a encrypting method that uses a mathematical function Ax+B to shift each letter in a given plaintext according to the letter's index in the alphabet. 对于不知道的人,这是一种加密方法,它使用数学函数Ax + B根据字母中的字母索引将给定明文中的每个字母移位。

I've written a code that encrypts and decrypts a given plaintext or ciphered text using Affine Cipher. 我编写了一个代码,使用Affine Cipher加密和解密给定的纯文本或密文。 It consists of these three functions: 它包含以下三个功能:

char *encryption(char Plaintext[MAXSIZE], int A, int B);
int modularinverse(int number, int modulo);
char *decryption(char Ciphered[MAXSIZE], int A, int B, int inverse);

The part that concerns me sites in the decryption function. 与我有关的部分位于解密功能中。 Around three or four letters are miss-calculated. 大约错失了三四个字母。

Let's consider the following plaintext: "abcde" 让我们考虑以下纯文本:“ abcde”

Using the encryption function: 使用加密功能:

char *encryption(char Plaintext[MAXSIZE], int A, int B) {
    static char Ciphered[MAXSIZE];
    int i;
    int y;
    int index;
    for (i = 0; i < strlen(Plaintext) - 1; i++) {
        if (Plaintext[i] == ' ') {
            Ciphered[i] = ' ';
        } else {
            index = (int)Plaintext[i] - 'a';
            y = (A * index + B) % 26;
            Ciphered[i] = (char)y + 97;
        }
    }
    return Ciphered;
}

it turns the plaintext into: "fmtah". 它把明文变成:“ fmtah”。 Which is correct. 哪个是对的。

Decrypting the plaintext should obviously give: "abcde". 解密明文显然应该给出:“ abcde”。 But instead, it gives: "abc J e". 但相反,它给出:“ abc J e”。

char *decryption(char Ciphered[MAXSIZE], int A, int B, int inverse) {
    static char NewPlaintext[MAXSIZE];
    int i;
    unsigned int x;
    int y;
    int index;
    for (i = 0; i < strlen(Ciphered); i++) {
        if (Ciphered[i] == ' ') {
            NewPlaintext[i] = ' ';
        } else {
            index = (int)Ciphered[i] - 'a';
            x = inverse * (index - B) % 26;
            NewPlaintext[i] = (char)x + 97;
        }
    }
    return NewPlaintext;
}

The letter d is miss-calculated for a reason I don't know. 字母d因我不知道的原因而计算错误。 Printing the values of variables index , inverse , B and x for each one of the characters fmtah will respectively return this: 为每个字符fmtah打印变量indexinverseBxfmtah将分别返回以下内容:

5         15        5         0
12        15        5         1
19        15        5         2
0         15        5         -23
7         15        5         4

First column represents indexes of the letters fmtah . 第一列代表字母fmtah索引。

Second column represents the inverse of A=7 , which is 15 . 第二列表示A=7的倒数,即15 (Totally harmful, you may ignore it). (完全有害,您可以忽略它)。

Third column represents B which is a constant for now (You may ignore it). 第三列代表B,目前它是一个常数(您可以忽略它)。

Fourth column represents x which is the result of inverse*(index-B) % 26 . 第四列表示x,它是inverse*(index-B) % 26 Adding 97 (ASCII number of 'a') to each of number in this column will result to the ASCII number of each letter. 在此列的每个数字上加上97(ASCII码“ a”)将得出每个字母的ASCII码。

ie 0+97 = 97 which is 'a'. 即0 + 97 = 97,即“ a”。 By consequence Decryption(f)=a. 结果,解密(f)= a。

But if you can notice. 但是,如果您可以注意到。 the result of x for the letter 'a' is -23. x表示字母“ a”的结果为-23。 -23+97=74 which is J in ASCII. -23 + 97 = 74,它是ASCII中的J。 It should rather be 100 as it's the ASCII number for d. 应该是100,因为它是d的ASCII码。 Therefore the result of x should rather be 3, not -23. 因此x的结果应该是3,而不是-23。

The reason behind this miss-calculation is buzzing me and I haven't figured out what's causing it. 这种错误计算背后的原因让我很困惑,我还没有弄清楚是什么原因造成的。

Your code has several problems: 您的代码有几个问题:

  • you stop before the end of the string: i<strlen(Plaintext)-1 您在字符串末尾之前停止: i<strlen(Plaintext)-1
  • you do not null terminate the destination strings. 您不能将null终止目标字符串。
  • your return a pointer to static storage: only one string can be encrypted/decyphered at a time. 您返回一个指向静态存储的指针:一次只能加密/解密一个字符串。
  • depending on the values, you may take the modulo of negative numbers, which will be negative too. 根据值,您可以取负数的模,也将为负。 Use this instead: x = ((inverse * (index - B) % 26) + 26) % 26; 改用它: x = ((inverse * (index - B) % 26) + 26) % 26;

Your code has few issues which are causing this strange behavior; 您的代码很少有导致这种奇怪行为的问题;

  1. Don't use int type if you are dealing with character. 如果要处理字符,请不要使用int类型。 Use char 使用char
  2. In decryption() handle if the value of x is negative. decryption()处理x值为负。

you can modify your decryption() like this. 您可以像这样修改您的decryption()

char *decryption(char Ciphered[MAXSIZE],int A, int B, int inverse)
{
    static char NewPlaintext[MAXSIZE];
    char x;
    char index;
    for(int i=0;i<strlen(Ciphered);i++)
    {
        if(Ciphered[i]==' ')
        {
            NewPlaintext[i]=' ';
        }
        else
        {
            index=(int)Ciphered[i] - 'a';
            x=inverse*(index-B) % 26;
            if(x < 0)
            {
                // add 26 to take care of negative values; since you are using %
                x += 26;
            }
            NewPlaintext[i]=(char)x+97;
        }
    }
    return NewPlaintext;
}

I tested it few entries and it works fine. 我测试了它几个条目,它工作正常。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM