2016-02-27 50 views
0

声明:无论以下情况如何,均与Affine Cipher相关。对于不知道它的人,这是一种使用数学函数Ax + B根据字母表中字母索引来移动给定明文中的每个字母的加密方法。C中的仿射密码无法正常工作

我写了一个代码,使用仿射密码对给定的明文或加密文本进行加密和解密。它由以下三个功能组成:

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); 

解密函数中涉及到我站点的部分。大约三四个字母是错过计算的。

让我们考虑下面的明文: “A B C d e” 的

使用加密函数:

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; 
} 

它变成明文分为: “F米T A H”。哪个是对的。

解密明文应该明显地给出:“a b c d e”。相反,它给出了:“a b c 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; 
} 

字母d由于我不知道的原因而错过计算。印刷变量indexinverseBx的人物f m t a h将分别返回这个每个人的价值观:

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

第一列代表的字母f m t a h的指标。

第二列代表A=7的倒数,即15。 (完全有害,你可以忽略它)。

第三列表示B现在是一个常数(您可以忽略它)。

第四列代表x是inverse*(index-B) % 26的结果。在该列中的每个数字上加97('a'的ASCII码)将导致每个字母的ASCII码。

即0 + 97 = 97这是'a'。由结果解密(f)= a。

但是,如果你能注意到。字母'a'的x的结果是-23。 -23 + 97 = 74这是ASCII码中的J。它应该是100,因为它是d的ASCII码。因此x的结果应该是3而不是-23。

这个错过计算背后的原因是嗡嗡我,我还没有想出是什么原因造成的。

+1

我假设你正在学习编码。如果是这样,自己解决问题,学习如何调试非常重要。添加打印语句,跟踪执行,添加断点,观察变量和** think **。 [Richard Feynman](https://en.wikipedia.org/wiki/Richard_Feynman)通过思考固定收音机。想想:“这怎么可能发生”? – zaph

+0

@zaph我试过了,但我想不通为什么编译器认为简单计算的结果是-23。我已经测试过它,它给了我3它应该是。 – Amine

+0

@Amine:编译器不会*思考*,它会生成代码,如果'B'大于'index',那么您编写的表达式可以具有负值。划分向'0'截去,'-23%26'评估为'-23'。 – chqrlie

回答

1

你的代码有几个问题导致这种奇怪的行为;

  1. 如果您正在处理字符,请勿使用int类型。使用char
  2. 如果x的值为负,则处理decryption()

你可以像这样修改你的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; 
} 

我测试了它很少的条目,它工作正常。

希望这会有所帮助。

+0

谢谢,它的作品。 – Amine

+0

@Amine你也需要修改你的encryption()方法。使用char而不是int。 –

+0

char而不是int在哪里?我已经将函数类型定义为char,并且它返回一个char – Amine

1

你的代码中有几个问题:

  • 将字符串结束前停止:i<strlen(Plaintext)-1
  • 你不空终止目标字符串。
  • 您返回一个指向静态存储的指针:一次只能加密/解密一个字符串。
  • 取决于数值,您可能会采用负数模,这也将是负数。代之以:x = ((inverse * (index - B) % 26) + 26) % 26;
+0

我在字符串的大小之前停止,因为它的大小是1024,因为它是definedi n MAXSIZE。这两个函数都会计算字符串的结尾\ 0 我不理解第二个,你应该在第三个函数中解释更多 – Amine

+0

@Amine:'strlen(Plaintext)'计算'Plaintext'中的字符数与'sizeof(Plaintext)'不同,''\ 0''在你的情况下是'char *'的大小,而不是作为参数传递的数组的大小。定义'char *加密(char Plaintext [MAXSIZE],int A,int B)''完全等价于'char * encryption(char * Plaintext,int A,int B)' – chqrlie

+0

我已经测试过了,没有使用-1。加密功能也将加密空白空间。“这是编译时没有减去-1从strlen – Amine