2012-11-15 34 views
5

我加密如下,但不知道如何防止大寫字符進入其他符號,如果他們被移出範圍,類似地小寫字母超出小寫字母的範圍。我怎樣才能讓他們圍成一圈並停止溢出?由於密碼溢出

int size = strlen(plain_text); 
int arrayelement = 0; 
for(arrayelement = 0; arrayelement < size; arrayelement++) 
{ 
    if (islower(plain_text[arrayelement])) 
    { 
     ciphered_text[arrayelement] = (int)(plain_text[arrayelement] + shiftkey); 
    } 
    else if (isupper(plain_text[arrayelement])) 
    { 
     ciphered_text[arrayelement] = (int)(plain_text[arrayelement] + shiftkey); 
    } 
} 

ciphered_text[size] = '\0'; 
printf("%s", ciphered_text); 

回答

1

我猜你使用類型,比如CHAR這樣一個簡單的解決方案,以不溢出是做

int tmp_ciphered = (my_char + shift) % 0xff; 
char ciphered = (char)(tmp_ciphered); 

thenyou轉而不會溢出,這是一個環

1

此副本(幾乎完全)c++ simple Caesar cipher algorithm

請注意,我不同意在該帖子上接受的答案。基本上你必須使用類似((c-'a'+ shift)%26)+'a'的方式將角色映射回範圍。然而,假設你的角色是'a'..'z'。可能會更安全地使用c> ='a'& & c < ='z'而不是islower,因爲我不確定區域設置在非英語系統上的播放方式。類似於isupper和其他範圍。最後,你需要一個else子句來處理char不在任何範圍內。

+0

%26在你的例子中做了什麼?謝謝 – user1827332

+0

除以26後的餘數(模數運算符) – DrC

+0

謝謝,不清楚如何((c-'a'+ shift)%26)+'a'將它放回到範圍內。 如果我通過4的移位密碼xyz,它返回|>〜 – user1827332

1

唯一真正的可移植的方法是爲輸入域建立一個查找表,並根據非線性假設手動構建字符。

即使對於的['a'..'z','A'..'Z']受限域,假設「A」 ..「Z」是連續是由語言標準定義,和可證明是並非總是如此。對於任何反對者的反對者,我會指示你在圖at this link中的字符順序位置,密切關注假設序列中間的死區。如果您認爲「沒有人再使用EBCDIC」,那麼讓我向您保證AS/400和OS/390都還活着(現在可能正在處理您的美國稅收,因爲IRS是IBM最大的客戶之一)。

事實上,C標準是很明確這一點:

C99-5.2.1.3在源和執行基本字符集,每個字符的0後在上述列表中的值的十進制數字應該大於前一個的值。

無處是有定義排序的甚至一提或甚至暗示排序上的字符集的任何其他部分。實際上,'0'..'9'還有另外一個獨特的屬性:它們是保證不受語言環境變化影響的唯一字符。

因此,不要假設字符的線性延續存在,而在標準的可疑沉默中翻閱我們的鼻子時,讓我們定義我們自己的硬件地圖。我不會像通常那樣將代碼嵌入到這裏;如果你仍然和我在一起,你真的有興趣知道並且可能會閱讀和批評下面的代碼。但我會總結它是如何工作的:

  1. 靜態聲明兩個字母,長度是雙倍的(A..ZA..Z,a..za..z)。
  2. 聲明兩個數組(加密和解密)足夠大,以容納(1<<CHAR_BIT)條目。
  3. 使用與其索引對應的值完全初始化這兩個數組。例如:a[0]=0a[1]=1,...
  4. 從(1)中填入我們字母部分的加密數組中的每個位置,使用對應於位移寬度Ex的適當值。 ROT5的a['a'] = 'g'
  5. 鏡像(4)從字母尾部向後工作,應用相反的移位方向。例如:`a ['g'] ='a';

現在,您可以使用加密陣列作爲一個簡單的表格輸入文本轉換爲密文:

enc-char = encrypt[ dec-char ]; 
dec-char = decrypt[ enc-char ]; 

如果你覺得這似乎是一個大量的工作只是爲了獲得源代碼級的平臺獨立性, 你是絕對正確的。但你會在驚訝在#ifdef #endif 地獄,人們試圖作爲「多平臺」傳遞。平臺無關代碼的核心目標不僅是定義通用源,還定義行爲。無論平臺如何,上面的概念都可以工作。 (而不是看到#ifdef)。

感謝您花時間閱讀這場慘敗。這樣一個看似簡單的問題...


樣品的main.cpp

#include <stdio.h> 
#include <stdlib.h> 
#include <limits.h> 
#include <string.h> 

// global tables for encoding. must call init_tables() before using 
static char xlat_enc[1 << CHAR_BIT]; 
static char xlat_dec[1 << CHAR_BIT]; 

void init_tables(unsigned shift) 
{ 
    // our rotation alphabets 
    static char ucase[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
    static char lcase[] = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"; 
    int i=0; 

    // ensure shift is below our maximum shift 
    shift %= 26; 

    // prime our table 
    for (;i<(1 << CHAR_BIT);i++) 
     xlat_enc[i] = xlat_dec[i] = i; 

    // apply shift to our xlat tables, both enc and dec. 
    for (i=0;i<(sizeof(ucase)+1)/2;i++) 
    { 
     xlat_enc[ lcase[i] ] = lcase[i+shift]; 
     xlat_enc[ ucase[i] ] = ucase[i+shift]; 
     xlat_dec[ lcase[sizeof(lcase) - i - 1] ] = lcase[sizeof(lcase) - i - 1 - shift]; 
     xlat_dec[ ucase[sizeof(ucase) - i - 1] ] = ucase[sizeof(ucase) - i - 1 - shift]; 
    } 
} 


// main entrypoint 
int main(int argc, char *argv[]) 
{ 
    // using a shift of 13 for our sample 
    const int shift = 13; 

    // initialize the tables 
    init_tables(shift); 

    // now drop the messsage to the console 
    char plain[] = "The quick brown fox jumps over the lazy dog."; 
    char *p = plain; 
    for (;*p; fputc(xlat_enc[*p++], stdout)); 
    fputc('\n', stdout); 

    char cipher[] = "Gur dhvpx oebja sbk whzcf bire gur ynml qbt."; 
    p = cipher; 
    for (;*p; fputc(xlat_dec[*p++], stdout)); 
    fputc('\n', stdout); 

    return EXIT_SUCCESS; 
} 

輸出

Gur dhvpx oebja sbk whzcf bire gur ynml qbt. 
The quick brown fox jumps over the lazy dog. 
0

你可以從字面上實現它:

「如果他們正在轉移d超出範圍「:

if (ciphered_text[arrayelement] > 'z') 

」讓他們去圓了一圈,並停止溢出「:

ciphered_text[arrayelement] -= 26; 

在您的上下文:

if (plain_text[arrayelement] >= 'a' && plain_text[arrayelement] <= 'z') 
{ 
    ciphered_text[arrayelement] = (int)(plain_text[arrayelement] + shiftkey); 
    if (ciphered_text[arrayelement] > 'z') 
     ciphered_text[arrayelement] -= 26; 
} 

(假設你用英語工作文本在ACSII編碼中,shiftkey在1 ... 25範圍內,就像它應該是的一樣)