0

だから私はシーザー暗号プログラムを作っています。暗号化はうまく機能しています。それは私が問題を抱えている復号化です。

大文字の暗号化に使用できるコードは次のとおりです。

        if (isupper(p[i])){
    char c = ((p[i] - 'A') + k % 26) + 'A';
     }

今、私は復号化が次のようになると思います:

        if (isupper(pp[i])){
    char c = (abs((p[i] - 'A') - k) % 26) + 'A';
     }

私が抱えている問題は、k=1かつp[i]='A'の場合、'Z'ではなく文字'B'を出力するだけで、k=2およびp [i]='A'文字'Y'を出力する必要があります。k=1かつp[i]='B'の場合に機能し、助けてくれてありがとう'A'を出力します。

4

3 に答える 3

1

これはそれを行う必要があります:

if (isupper(p[i])){
    char c = (p[i] - 'A' + 26 - k) % 26) + 'A';
}

+ 26あなたにあなたのラッピングを与えます

このように考えてください(3桁の数値形式は、物事をうまく並べるためだけのものです):

| 000 | 001 | 002 | ... | 024 | 025 | plain
|  A  |  B  |  C  | ... |  Y  |  Z  |
| 003 | 004 | 005 | ... | 001 | 002 | crypto

今、それを認識してください

(n + 26) % 26 === (n % 26)

それで:

| 000 | 001 | 002 | ... | 024 | 025 | plain
|  A  |  B  |  C  | ... |  Y  |  Z  |
| 029 | 030 | 031 | ... | 053 | 054 | crypto

26を法とする場合、上記と同等です。

これにより、生活がずっと楽になります。平文記号セットは、からまでの連続した整数のセットで構成さ'A''A' + 25ます。問題は、暗号文シンボルセットが連続していないことです...で不連続性があり025ます。'A' + k + 2626を追加することにより、暗号文をからまでの連続した範囲に変換できます'A' + k + 49

隣接する暗号文シンボルセットを平文シンボルセットにマップする方がはるかに簡単です。

シーザーコードはどちらの方向にもシフトする可能性があり、復号化は正反対のシフトであるため、これを次のように組み合わせることができます。

boolean decrypt;
int k; 
...
k = k % 26; // Ensure that the shift doesn't include any wrapping
if(decrypt) {
    k *= -1;
}
if (isupper(p[i])){
    char c = (p[i] - 'A' + 26 + k) % 26) + 'A';
}
于 2012-10-18T21:56:21.283 に答える
0

暗号化では、

((p[i] - 'A') + k % 26) + 'A'

次のように評価されていると考えてください

t1 = p[i] - 'A'
t2 = k % 26
result = t1 + t2 + 'A'

それはおそらくあなたが意図したものではありません。復号化によってその計算が逆転することはありません。これは主に、追加のグループ化によって操作の順序が変わるためです。

于 2012-10-18T21:51:00.833 に答える
0

あなたは彼らが包み込むという事実を考慮していません、このようにそれを試してください:

if ((p[i] - 'A' - k) < 0 )
    c = 'Z' - (abs(p[i] - 'A' - k) % 26) + 1;
else 
    c = (abs(p[i] - 'A' - k) % 26) + 'A';

そして、私はあなたもムドゥロ「%」を必要としないと思います。

于 2012-10-18T21:55:03.750 に答える