使用xor操作来加密struct元素

时间:2010-12-04 21:13:27

标签: c encryption xor

我在C中编写了一个程序,用每个字符中的xor操作加密结构的元素。

当我使用包含非数字字符的密码时,代码正常运行。但是,如果密码包含数字字符,则结构的元素不能完全打印。 这是文件的内容(文件名是'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));
        }
    }

}

1 个答案:

答案 0 :(得分:4)

由于您提供了输入文件的内容,我几乎可以肯定主要的问题是您在加密文本上使用了面向字符串的string.h和stdio.h函数。

考虑一下:您的输入文件主要由数字组成,您的问题密码也包含数字。与自身进行异或的字符将产生一个零字节,大多数处理字符串的C函数都会将其视为字符串的结尾!

编辑:

处理这个问题的方法是在每个缓冲区附带一个整数,表示其中的字符数,然后坚持使用内存区域操作函数,如memcpy,memcmp等。你还应该避免使用* puts ()和* gets()用于文件I / O,因为它们也是面向字符串的。

编辑2:

基本上,您应该将输入文件视为包含未知内容的二进制文件,而不是文本文件。这将使您的代码更加强大和通用,但这也意味着您不能使用任何str *()函数。