2

I'm writing a program in C that reads text from a file, takes a password as an argument, creates a string of the same length as the input string, and does a char-by-char XOR operation of it, outputting encoded text to another file, which can then be reversed by the same process. My problem is this: a character XOR itself is the ASCII null character, which is causing me trouble reading or writing somewhere. I'm not sure if ASCII 0 is read as EOF, '\0', or both. The input part of my code looks like this:

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

My output section looks like this:

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;

My XOR function looks like:

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

This is a problem when my encoding file is, say, "I like books!" and my password is "foo", because it goes

 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

In this example, my output file shows the F, but not the G, meaning it terminates around the null character. Is there any way for null characters to go through the process, maybe involving the length? Sorry for the long post, and thank you for your time!

3 Answers3

2

You cannot use "string" functions with char arrays that are not strings. You have to print its contents with some other method.

printf("encoded:");
for (int k = 0; k < length; k++) {
    printf(" %02x", encodedString[k]);
}
printf("\n");
pmg
  • 106,608
  • 13
  • 126
  • 198
1

'\0' ascii(0) and (char)0 are the same and they all terminate strings.

If you want to be able to handle embedded '\0' characters in your data you need to keep track of the length in a separate variable and you cannot rely on any string functions.

In your case, the output routing needs a modification:

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

Note that some text editors have problems with files containing embedded '\0'.

Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
1

Encoded data has '\0' characters so you must write it as binary data. Corrections to your 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;
Rimas
  • 5,904
  • 2
  • 26
  • 38