唯一真正的可移植的方法是爲輸入域建立一個查找表,並根據非線性假設手動構建字符。
即使對於的['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'
還有另外一個獨特的屬性:它們是保證不受語言環境變化影響的唯一字符。
因此,不要假設字符的線性延續存在,而在標準的可疑沉默中翻閱我們的鼻子時,讓我們定義我們自己的硬件地圖。我不會像通常那樣將代碼嵌入到這裏;如果你仍然和我在一起,你真的有興趣知道並且可能會閱讀和批評下面的代碼。但我會總結它是如何工作的:
- 靜態聲明兩個字母,長度是雙倍的(A..ZA..Z,a..za..z)。
- 聲明兩個數組(加密和解密)足夠大,以容納
(1<<CHAR_BIT)
條目。
- 使用與其索引對應的值完全初始化這兩個數組。例如:
a[0]=0
,a[1]=1
,...
- 從(1)中填入我們字母部分的加密數組中的每個位置,使用對應於位移寬度Ex的適當值。 ROT5的
a['a'] = 'g'
。
- 鏡像(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.
%26在你的例子中做了什麼?謝謝 – user1827332
除以26後的餘數(模數運算符) – DrC
謝謝,不清楚如何((c-'a'+ shift)%26)+'a'將它放回到範圍內。 如果我通過4的移位密碼xyz,它返回|>〜 – user1827332