C中的字符串XOR函数:如何处理空字符?

时间:2014-09-08 08:29:39

标签: c string io xor null-character

我正在用C编写一个程序,它从文件中读取文本,将密码作为参数,创建一个与输入字符串长度相同的字符串,并对其进行char-by-char XOR操作,将编码文本输出到另一个文件,然后可以通过相同的过程进行反转。我的问题是:字符XOR本身是ASCII空字符,这使我在某处读取或写入时遇到麻烦。我不确定ASCII 0是读作EOF,'\ 0'还是两者都读。我的代码的输入部分如下所示:

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

我的输出部分如下所示:

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;

我的XOR功能如下:

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

当我的编码文件是“我喜欢书籍”时,这是一个问题。我的密码是“foo”,因为它是

 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

在此示例中,我的输出文件显示F,但不显示G,这意味着它以空字符结尾。有没有办法让空字符完成整个过程,可能涉及长度?对不起,很长的帖子,谢谢你的时间!

3 个答案:

答案 0 :(得分:2)

你不能使用&#34; string&#34;具有不是字符串的char数组的函数。您必须使用其他方法打印其内容。

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

答案 1 :(得分:1)

'\0' ascii(0)(char)0是相同的,它们都会终止字符串。

如果您希望能够处理数据中的嵌入式'\0'字符,则需要在单独的变量中跟踪长度,并且不能依赖任何字符串函数。

在您的情况下,输出路由需要修改:

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

请注意,某些文本编辑器存在包含嵌入式'\0'的文件的问题。

答案 2 :(得分:1)

编码数据有'\0'个字符,因此您必须将其写为二进制数据。对代码的更正:

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;