2

我正在用 C 语言编写一个程序,它从文件中读取文本,将密码作为参数,创建一个与输入字符串长度相同的字符串,并对它进行逐字符异或运算,输出编码文本到另一个文件,然后可以通过相同的过程将其反转。我的问题是这样的:字符 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,这意味着它以空字符结尾。有没有办法让空字符通过这个过程,可能涉及长度?抱歉发了这么长的帖子,感谢您的宝贵时间!

4

3 回答 3

2

您不能将“字符串”函数用于非字符串的 char 数组。您必须使用其他方法打印其内容。

printf("encoded:");
for (int k = 0; k < length; k++) {
    printf(" %02x", encodedString[k]);
}
printf("\n");
于 2014-09-08T08:34:56.333 回答
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;
于 2014-09-08T08:45:26.343 回答
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'.

于 2014-09-08T08:40:32.023 回答