2016-02-27 48 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