-2

C で簡単な暗号化プログラムを作成しようとしています。私の目的は、「jim」(任意の単語である可能性があります) を 10,9,13 に変換することです。次に、プラス 1,2,3 (単語には 3 文字があるため) を取得し、11,12,16 を取得してから、再びテキストに変換し、画面 klp に書き込みます。動作しますが、これらの単語については、最初のアルゴリズムを開始してから2番目のアルゴリズム(逆)を開始すると、「実行可能なコンパイラ」という問題があります。

PS:unencrypted.txtという名前のmake txtファイルを実行し、内部に単語を書き込み、最初のアルゴリズム、次に2番目のアルゴリズムを実行したい場合

int main() {
    int g,z,o,c,l,i,j,k,*D;

    char alfabe[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    FILE *fp1;
    FILE *mat;
    char word[20];

    fp1 = fopen("unencrypted.txt","r+");
    do {
        g = fscanf(fp1,"%s",word);
        if (g != EOF) {
            mat=fopen("encrypted.txt","a+");
            c=strlen(word);
            D=(int*)calloc(c,sizeof(int));
            for(i=0;i<c;i++) {
                for(j=0;j<26;j++) {
                    if(word[i]==alfabe[j]) {
                         D[i]=(((j+1)+(i+1))%26);
                         break;
                    }
                }
            }
        }

        for(z=0;z<c;z++){
              o=D[z];
              word[z]=alfabe[o-1];
        }

        for(k=0;k<c;k++) {
           fprintf(mat,"%c",word[k]);
        }
        fprintf(mat," ");
        fclose(mat);

    } while (g != EOF);
    fclose(fp1);
}

int main() {
    int g,z,o,c,l,i,j,k,*D;

    char alfabe[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    FILE *fp1;
    FILE *mat;
    char word[20];

    fp1 = fopen("encrypted.txt","a+");
    do {
        g = fscanf(fp1,"%s",word);
        if (g != EOF) {
            mat=fopen("unencrypted1.txt","a+") ;
            c=strlen(word);
            D=(int*)calloc(c,sizeof(int));
            for(i=0;i<c;i++) {
                for(j=0;j<26;j++) {
                    if(word[i]==alfabe[j]) {
                        if(0>((j+1)-(i+1))){
                            D[i]=((j+1)-(i+1)+26);
                        } else D[i]=((j+1)-(i+1));
                        break;
                    }
                }
            }
        }

        for(z=0;z<c;z++){
            o=D[z];
            word[z]=alfabe[o-1];
        }

        for(k=0;k<c;k++) {
           fprintf(mat,"%c",word[k]);
        }
        fprintf(mat," ");
        fclose(mat);

    } while (g != EOF);
    fclose(fp1);
}
4

1 に答える 1

0

まず、暗号化ルーチンでは、未定義の動作をすることができます:

word[z]=alfabe[o-1];

o == 0は、単語内の文字の 1 ベースのインデックスとアルファベット内の 1 ベースのインデックスの合計が 26 の倍数である場合に、メモリにアクセスすべきではありません。

これを回避するには、 を設定word[z] = alfabe[(o+25)%26]するか、+1前のループの の 1 つを省略して を使用しますalfabe[o]

のアクセスはalfabe[-1]、発生した場合、セグメンテーション違反や同様の劇的な問題を引き起こす可能性が低い未定義の動作の一種であり、暗号化された単語に予期しないバイトが書き込まれるだけです。

復号化では、同様の問題があり、

if(0>((j+1)-(i+1))){
    D[i]=((j+1)-(i+1)+26);
} else D[i]=((j+1)-(i+1));

単語が十分に長い場合、j - i + 26否定的である可能性もあります (ただし、他の多くの言語でも、自然な英語のテキストではほとんどありません)。

繰り返しになりますがD[i]、0 に設定されている場合があります。

for(z=0;z<c;z++){
    o=D[z];
    word[z]=alfabe[o-1];
}

再びアクセスalfabe[-1]し、未定義の動作を引き起こします。

また、入力に小文字と空白以外のものが含まれている場合 (これは によって破棄されますfscanf)、D配列の対応するエントリには、そのメモリ位置に発生したバイトが含まれ、未定義の動作が発生することにも注意してください。

入力に小文字 (および空白) のみが含まれている場合は、ループよりもはるかに簡単にアルファベットのインデックスを見つけることができます。

j = word[i] - 'a';

この問題を回避するにはalfabe[-1]、0 ベースのインデックスを使用することをお勧めします。

于 2012-05-09T22:01:01.307 に答える