2010-12-04 5 views
1

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

数値以外の文字を含むパスワードを使用すると、コードが正常に実行されます。しかし、パスワードに数字が含まれている場合、構造体の要素は完全には印刷できません。ここで

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)); 
     } 
    } 

} 
+5

"印刷できません" - なぜ暗号化されたテキストを印刷したいですか?すべての意図と目的に対して、暗号化されたバイナリです。 –

+4

私はあなたのコードを読んでいないが、それは非常に危険である可能性が最も高い。キーストリームを生成するために良いストリーム暗号化(またはワンタイムパッド)を使用し、**再利用しない限り、xor暗号化は安全ではありません。特に、パスワードを繰り返し、キーストリームとして使用することは安全ではありません。 – CodesInChaos

+2

私はコードをよく見ていませんでしたが、一般にXOR暗号化の後では、出力でゼロバイトを得ることができます。つまり、暗号化されたテキストに文字列関数(strcmp、strlen、strncpyなど)を使用することは正しくありません。 – thkala

答えて

4

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

あなたの入力ファイルはほとんどが数字で構成されており、問題のパスワードには数字も含まれています。 XORされた文字はゼロバイトを生成し、文字列を扱うほとんどのC関数は文字列の最後と認識します。

EDIT:

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

EDIT 2:

基本的には、未知の内容のバイナリファイルではなく、テキストファイルとして入力ファイルを扱う必要があります。これはあなたのコードをより堅牢で多用途にするでしょうが、str *()関数を使うことはできません。

+0

問題は ''それ自体ではなく、 ''の間違った機能を使用しています。具体的には、 'fread()'と 'fwrite()'を使う方が正しいでしょう。 –

+0

本当です!おそらくxor演算がヌル文字を生成しています。私が '1'xor'1'を実行すると、文字列の最後を示すヌル文字が生成されます。 – adriano

+0

@Jonathan Leffler:私はこの点について私の答えをより明確にしました。ありがとう – thkala

関連する問題