これを行うための真に移植可能な唯一の方法は、入力ドメインのルックアップ テーブルを構築し、非線形の仮定に基づいて手動で文字を構築することです。
の制限されたドメインであっても、['a'..'z','A'..'Z']
「A」..「Z」が連続していると仮定することは、言語標準によって定義されておらず、常にそうであるとは限りません。そうでないと考える否定論者のために、想定されるシーケンスの真ん中にあるデッドゾーンに細心の注意を払いながら、このリンクのチャート内の文字の順序位置を案内します. 「もう誰も EBCDIC を使用していない」と思われる場合は、AS/400 と OS/390 の両方が正常に機能していることを保証させてください (IRS は IBM の最大の顧客の 1 つであるため、おそらく現在、米国の税金を処理しています)。
実際、C 標準はこれについてかなり明示的です。
C99-5.2.1.3ソースと実行の両方の基本文字セットで、上記の 10 進数のリストで 0 の後の各文字の値は、前の値よりも 1 大きくなければなりません。
文字セットの他の部分で定義された順序付けや暗黙の順序付けについての言及さえどこにもありません。実際に'0'..'9'
は、もう 1 つの固有の属性があります。ロケールの変更によって影響を受けないことが保証されている唯一の文字です。
したがって、標準の疑わしい沈黙に鼻を鳴らしながら、キャラクターに線形の継続が存在すると仮定するのではなく、独自のハードマップを定義しましょう. ここでは、通常のようにコードをインライン化しません。あなたがまだ私と一緒にいるなら、あなたは本当に知りたいと思っており、おそらく以下のコードを読んで批評するでしょう. しかし、それがどのように機能するかを要約して説明します。
- 2 倍の長さの 2 つのアルファベットを静的に宣言します (A..ZA..Z、a..za..z)。
(1<<CHAR_BIT)
エントリを保持するのに十分な大きさの 2 つの配列 (暗号化と復号化) を宣言します。
- インデックスに対応する値で両方の配列を完全に初期化します。例:
a[0]=0
、a[1]=1
、...
- (1) のアルファベットの一部である暗号化配列の各位置に、シフト幅 Ex に対応する適切な値を入力します。
a['a'] = 'g'
ROT5の場合。
- 反対のシフト方向を適用して、アルファベットの末尾から逆方向に作業することにより、(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.