2014-09-08 3 views
1

J'écris un programme en C qui lit du texte à partir d'un fichier, prend un mot de passe comme argument, crée une chaîne de la même longueur que la chaîne d'entrée, et effectue une opération XOR char-by-char, produisant texte codé dans un autre fichier, qui peut ensuite être inversé par le même processus. Mon problème est le suivant: un caractère XOR lui-même est le caractère ASCII nul, ce qui me cause des problèmes de lecture ou d'écriture quelque part. Je ne suis pas sûr si ASCII 0 est lu comme EOF, '\ 0', ou les deux. La partie d'entrée de mon code ressemble à ceci:fonction XOR chaîne dans C: Comment faire face à des caractères nuls?

int main(int argc, char *argv[]) 
{ 
    if(argv[1]==NULL)       /*makes sure there is an input and password,   respectively*/ 
    return 1; 
    if(argv[2]==NULL) 
    return 2; 
    FILE *fpi = fopen(argv[1],"rb"); 
    char *inputText; 
    fseek(fpi, 0L, SEEK_END);      /*finds end of file, reads size, and then sets to beginning of stream*/ 
    int fileSize = ftell(fpi); 
    fseek(fpi, 0L, SEEK_SET); 

    inputText = malloc(fileSize+1); 
    size_t size=fread(inputText,1,fileSize,fpi); 
    inputText[size]=0; 


    fclose(fpi); 

Ma section de sortie ressemble à ceci:

char *encodedString = xorString(plainText, passwordCode, textLength, twoToThe); /*call to xor function*/ 
FILE *fpo; 
if(argv[3]!=NULL) 
{ 
    fpo = fopen(argv[3],"w"); 
} 
else 
{ 
    fpo = fopen(OUTPUT_FILE,"w"); 
} 
fprintf(fpo, "%s", encodedString); 
fclose(fpo); 
return 0; 

Ma fonction XOR ressemble:

char *xorString(char *plainString, char * passString, int length, int *powsOfTwo) 
{ 
    char *codedString = malloc((sizeof (char)) * length + 1); 
    int i; 
    for(i=0; i<length; i++)      
    { 
    codedString[i] = plainString[i]^passString[i]; 
    } 
    return codedString; 
} 

Ceci est un problème quand mon fichier d'encodage est, disons, "J'aime les livres!" et mon mot de passe est « foo », car il va

I^f =/
^o = 0 
l^o = (ASCII 3) 
i^f = (ASCII 15) 
k^o = (ASCII 4) 
e^o = '\n'(ASCII 10) 
^f = F 
b^o = '\r'(ASCII 13) 
o^o = (ASCII 0)!!!!!! 
o^f = (ASCII 9) 
k^o = (ASCII 4) 
s^o = (ASCII 28) 
!^f = G 

Dans cet exemple, mon fichier de sortie affiche le F, mais pas le G, ce qui signifie qu'il se termine autour du caractère nul. Y a-t-il un moyen pour que les caractères nuls passent par le processus, impliquant peut-être la longueur? Désolé pour le long post, et merci pour votre temps!

+1

Votre erreur fondamentale est de confondre les données binaires avec du texte. Arrêter de faire ça. –

+0

Mauvaise chance. Vous avez besoin d'une fonction Injective qui mappe 256 valeurs à 255 valeurs, ce qui est mathématiquement impossible. –

Répondre

2

Vous ne pouvez pas utiliser les fonctions "chaîne" avec des tableaux de char qui ne sont pas des chaînes. Vous devez imprimer son contenu avec une autre méthode.

printf("encoded:"); 
for (int k = 0; k < length; k++) { 
    printf(" %02x", encodedString[k]); 
} 
printf("\n"); 
1

'\0'ascii(0) et (char)0 sont les mêmes et ils terminent tous les cordes.

Si vous souhaitez gérer les caractères '\0' intégrés dans vos données, vous devez garder la trace de la longueur dans une variable distincte et vous ne pouvez vous fier à aucune fonction de chaîne.

Dans votre cas, le routage de sortie a besoin d'une modification:

//fprintf(fpo, "%s", encodedString); // Doesn't work with embedded '\0' characters 
fwrite(fpo, encodedString, length); // Works with embedded '\0' characters 

Notez que certains éditeurs de texte ont des problèmes avec les fichiers contenant intégrés '\0'.

1

Les données codées ont '\0' caractères, vous devez donc les écrire en tant que données binaires. Corrections à votre code:

char *encodedString = xorString(plainText, passwordCode, textLength, twoToThe); /*call to xor function*/ 
FILE *fpo; 
if(argv[3]!=NULL) 
{ 
    fpo = fopen(argv[3],"wb"); // open in binary mode! 
} 
else 
{ 
    fpo = fopen(OUTPUT_FILE,"wb"); // open in binary mode! 
} 
fwrite(encodedString, sizeof(char), textLength, fpo); // write as binary data! 
fclose(fpo); 
free(encodedString); // avoid memory leak 
return 0; 
Questions connexes