1

各文字で xor 操作を使用して構造体の要素を暗号化するプログラムを C で作成しました。

数字以外の文字を含むパスワードを使用すると、コードは正常に実行されます。ただし、パスワードに数字が含まれている場合、構造体の要素は完全には印刷できません。ファイルの内容は次のとおりです (ファイルの名前は「input」です)。

500
0 25
5
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

コードは次のとおりです。

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

//This structure stores the file data
typedef struct arqc{
    char* npontos;
    char* carta;
    char* ordem;
    char** matriz;
}Arqc;

int learq( Arqc* fp, FILE* arq );
char criptografa( char ch, char chave );
void decriptografa( Arqc* fp, char* chave, int tam_matriz );

int main()
{
    FILE* arq = fopen("input.txt","r");
    Arqc* fp;
    int i;
    int tam;
    char* chave = "adr";
    fp = (Arqc*) malloc(sizeof(Arqc));
    if( fp == NULL )
        exit(-1);
    tam = learq( fp, arq );
    decriptografa( fp, chave, tam );
    puts( fp->npontos);
    puts( fp->carta);
    puts( fp->ordem);
    for( i = 0; i < tam ; i++){
        puts( *(fp->matriz + i));
    }

    decriptografa( fp, chave, tam );
    puts( fp->npontos);
    puts( fp->carta);
    puts( fp->ordem);
    for( i = 0; i < tam ; i++){
        puts( *(fp->matriz + i));
    }

    for( i = 0; i < tam ; i++){
        free( *(fp->matriz + i));
    }
    free(fp->npontos);
    free(fp->carta);
    free(fp->ordem);
    free(fp);
    fclose( arq );
    return 0;
}

//read the file and stores it in a struct
int learq( Arqc* fp, FILE* arq ){
    int i = 0;
    int tam;
    int n;
    int sair = 1;
    char aux[101];//stores a string read from the file
    /* *************************************************** */
    //this stretch every element of the struct will be filled
    // with the characters in each line of the file
    fgets( aux, 10, arq);
    tam = strlen( aux );
    fp->npontos = (char*) malloc(tam*sizeof(char));
    strncpy( fp->npontos, aux, tam - 1);
    *(fp->npontos + tam - 1) = '\0';
    fgets( aux, 10, arq);
    tam = strlen( aux );
    fp->carta = (char*) malloc(tam*sizeof(char));
    strncpy( fp->carta, aux, tam - 1);
    *(fp->carta + tam - 1) = '\0';
    fgets( aux, 10, arq);
    tam = strlen( aux );
    fp->ordem = (char*) malloc(tam*sizeof(char));
    strncpy( fp->ordem, aux, tam - 1);
    *(fp->ordem + tam - 1) = '\0';
    /* ************************************************** */
    //read here is the character corresponding to the order of the matrix
    //that is converted to the corresponding integer
    n = atoi(fp->ordem);
    //llocating the number of rows of the matrix
    fp->matriz = ( char**) malloc( n*sizeof(char*));
    while( sair ){
        //while the file is not closed, the struct will receive the file data
        if( fgets( aux, 101, arq) != NULL){
            tam = strlen( aux );
            *(fp->matriz + i) = (char*) malloc(tam*sizeof(char));
            strncpy( *(fp->matriz + i), aux, tam - 1);
            *(*(fp->matriz + i) + tam - 1) = '\0';
            i++;
        }
        else
            sair = 0;
    }
 //retorna a dimensão da matriz
 return n;
}

//criptografa cada caractere ch com um caractere chave
char criptografa( char ch, char chave ){
     ch = ( ch&~chave)|(~ch&chave);
     return ch;
}

//decrypts the file that was stored in fp using 'chave' to decrypt
void decriptografa( Arqc* fp, char* chave, int tam_matriz ){
    char aux[101];
    int i, j;
    int n;
    int tchave;
    strcpy( aux, fp->npontos);
    n = strlen( aux );
    tchave = strlen( chave );
    for( i = 0; i < n; i++){
        //decrypts each character read from the struct using the 'chave' characters
        *(fp->npontos + i) = criptografa( *(fp->npontos + i), *(chave + i%tchave));
    }
    strcpy( aux, fp->carta);
    n = strlen( aux );
    for( i = 0; i < n; i++){
        //decrypts each character read from the struct using the 'chave' characters
        *(fp->carta + i) = criptografa( *(fp->carta + i), *(chave + i%tchave));
    }
    strcpy( aux, fp->ordem);
    n = strlen( aux );
    for( i = 0; i < n; i++){
        //decrypts each character read from the struct using the 'chave' characters
        *(fp->ordem + i) = criptografa( *(fp->ordem + i), *(chave + i%tchave));
    }
    for( i = 0; i < tam_matriz; i++){
        strcpy( aux, *(fp->matriz + i));
        n = strlen( aux );
        for( j = 0; j < n; j++){
            //decrypts each character read from the struct using the 'chave' characters
            *(*(fp->matriz + i) + j) = criptografa( *(*(fp->matriz + i) + j), *(chave + i%tchave));
            printf("%c\n", *(*(fp->matriz + i) + j));
        }
    }

}
4

1 に答える 1

4

入力ファイルのコンテンツを提供したので、主な問題は、暗号化されたテキストでの文字列指向の string.h および stdio.h 関数の使用にあるとほぼ確信しています。

考えてみてください。入力ファイルはほとんどが数字で構成されており、問題のパスワードにも数字が含まれています。それ自体で XOR された文字は、文字列を扱うほとんどの C 関数が文字列の末尾として認識する 0 バイトを生成します!

編集:

この問題に対処する方法は、各バッファに文字数を示す整数を付けて、memcpy、memcmp などのメモリ領域操作関数に固執することです。また、*puts() と*gets() ファイル I/O も文字列指向であるため。

編集2:

基本的に、入力ファイルはテキスト ファイルではなく、内容が不明なバイナリ ファイルとして扱う必要があります。これにより、コードがより堅牢で用途の広いものになりますが、str*() 関数を使用できないことも意味します。

于 2010-12-04T21:48:24.753 に答える