开发者

using xor operation to encrypting struct elements

I wrote a pro开发者_如何学JAVAgram in C that encrypts elements of a struct with xor operation in each character.

When I use a password that contains non-numeric characters the code runs normally. But if the password contains numeric characters, elements of the struct are not fully printable. Here is the contents of file (the name of file is '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

Here's the code:

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

}


Since you provided the content of your input file, I am almost certain that the main problem is your use of string-oriented string.h and stdio.h functions on the encrypted text.

Think about it: your input file is mostly made out of numbers and your problem password also contains numbers. A character XOR'ed with itself will produce a zero byte which most C functions that deal with strings will perceive as the end of the string!

EDIT:

The way to deal with this issue is to accompany each buffer with an integer that will indicate the number of characters in it, and then stick to the memory area manipulation functions such as memcpy, memcmp etc. You should also avoid *puts() and *gets() for file I/O, since those are also string-oriented.

EDIT 2:

Basically you should treat your input file as a binary file with unknown contents, rather than a text file. This would make your code more robust and versatile, but it also means that you cannot use any of the str*() functions.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜