2016-07-14 72 views
0

我一直在研究凱撒密碼問題,但遇到了一個小問題。 無論什麼時候密碼值越多,'z'ascii,我想它反彈到'a',但我無法弄清楚如何這樣做。 下面是代碼:凱撒密碼不能正常工作C

#include <cs50.h> 
#include <ctype.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(int argc, string argv[]) 
{ 
    if(argc !=2 && !isdigit(argv[1])) 
    { 
     return 1; 
    } 

    //convert input to int and get the string 
    int k = atoi(argv[1]); 
    k=k%26; 
    //printf("%d" ,k); 
    //get he text 

    char *s; 
    s=GetString(); 
    int i, n=strlen(s); 

    //checking each character 
    for(i=0;i<n;i++) 
    { 
     if(s[i]==' ') 
     { 
      s[i]=' '; 
     } 
     else 
     { 
      s[i]=s[i]+k; 
     } 
     printf("%c" ,s[i]); 
    } 

} 

這是一個非常基本的代碼。任何幫助將不勝感激。

P.S.這裏是關鍵4.

input- Vinay Dawani 
output- Zmre} He{erm 
+1

當鍵是4時'z'和'Z'會發生什麼? –

+2

歡迎來到Stack Overflow。請儘快閱讀[關於]頁面。 SO上有許多凱撒密碼實現的問題。他們大多會告訴你解決你的問題的方法。你真的看看(一些)他們。看起來你並沒有試圖解決這個問題 - 你只知道你已經掌握了它。你應該展示你的嘗試。 (此外,在某些時候,您必須決定如何處理數字和標點符號,此刻,您將它們視爲字母,這可能不是最佳選擇。) –

+0

請在此代碼片段中查看: _http://ideone.com/QwOl1s_ –

回答

-1

添加k信後,檢查它是否比z更高的一個例子。如果是這樣,只需減去字母表中的字母數量即可。

s[i] = s[i]+k; 
if (s[i] > 'z') { 
    s[i] = s[i] - 26; 
} 

要處理大小寫,需要在主循環中單獨測試。

for(i=0;i<n;i++) 
{ 
    if(islower(s[i])) 
    { 
     s[i] += k; 
     if (s[i] > 'z') { 
      s[i] -= 26; 
     } 
    } 
    else if (isupper(s[i])) 
    { 
     s[i] += k; 
     if (s[i] > 'Z') { 
      s[i] -= 26; 
     } 
    } 
    printf("%c" ,s[i]); 
} 

注意,我刪除了測試if (s[i] == ' ')。這不是必要的 - 任何不是字母的東西都是單獨存在的。

+0

但@Barmar,這個代碼只有當我只想改變小寫字母時。 –

+0

也許更簡單的是在添加之後以26爲模。即:s [i] =(s [I] + k)%26。 –

+0

在你的'if()'中爲'islower(s [i])'和'isupper(s [i])'使用不同的情況。然後你可以比較'z'和'Z'。 – Barmar

0

假設在使用中設定的代碼不是EBCDIC(其具有在字母字符之間的非字母字符),則拉丁字母(重音A-Z)的字母被編碼爲在所有常見的代碼集的連續的代碼點。當你知道如何的時候,字母表的旋轉很簡單。

從根本上說,就轉換每個字母成從aA(取決於情況)信偏移0..25,添加編碼密鑰,取結果的模26中,並添加起始字母(aA)背部。請注意,算術運算爲int,但結果被分配回(可能已簽名)char

#include <cs50.h> 
#include <ctype.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(int argc, string argv[]) 
{ 
    if (argc != 2 || !isdigit((unsigned char)argv[1][0])) 
    { 
     fprintf(stderr, "Usage: %s shift\n", argv[0]); 
     return 1; 
    } 

    // convert input to int and get the string 
    int k = atoi(argv[1]) % 26; 
    if (k < 0) 
     k += 26; 

    char *s = GetString(); 
    int n = strlen(s); 

    printf("Original: [%s]\n", s); 

    // encoding each character 
    for (int i = 0; i < n; i++) 
    { 
     if (isupper((unsigned char)s[i])) 
     { 
      s[i] = 'A' + (s[i] - 'A' + k) % 26; 
     } 
     else if (islower((unsigned char)s[i])) 
     { 
      s[i] = 'a' + (s[i] - 'a' + k) % 26; 
     } 
    } 

    printf("Encrypted: [%s]\n", s); 
    return 0; 
} 

實施例運行:

$ ./caesar13 3 
Caesar's cipher is hardly secure against the lazy dog jumping over the quick brown fox, is it? 
Original: [Caesar's cipher is hardly secure against the lazy dog jumping over the quick brown fox, is it?] 
Encrypted: [Fdhvdu'v flskhu lv kdugob vhfxuh djdlqvw wkh odcb grj mxpslqj ryhu wkh txlfn eurzq ira, lv lw?] 
$ ./caesar50 23 
Fdhvdu'v flskhu lv kdugob vhfxuh djdlqvw wkh odcb grj mxpslqj ryhu wkh txlfn eurzq ira, lv lw? 
Original: [Fdhvdu'v flskhu lv kdugob vhfxuh djdlqvw wkh odcb grj mxpslqj ryhu wkh txlfn eurzq ira, lv lw?] 
Encrypted: [Caesar's cipher is hardly secure against the lazy dog jumping over the quick brown fox, is it?] 
$ 

CS50 library是現成的聯機。

+0

EBCDIC仍然是一件事?但世界上大部分地區都使用拉丁字母表外的字符(無音節的a-z)。 – zaph

+0

@ zaph:這取決於你工作的機器。大部分是「否」,但IBM大型機或與之相關的系統仍然可以使用EBCDIC。這主要是一個警告,即'z' - 'a''的值不能保證爲25,儘管這是迄今爲止最常見的值。這是CMA的評論 - 只要本地代碼集不是EBCDIC,代碼就可以。我想我可以添加一個斷言,比如'assert('z' - 'a'== 25);'或者靜態斷言,比如'_Static_assert('z' - 'a'== 25,「Code set not支持連續字母表「);'代碼中的某處。 –