Xor加密器新线路问题

时间:2016-09-02 20:42:48

标签: c fgets fread

我创建了一个简单的程序,它将现有文件作为输入(文本内容)加密其内容,并将加密内容输出到具有用户指定文件名的文件({{1} })。问题是每当argv[2]尝试读取新行字符时它就会终止。所以我想用fgets代替来解决这个问题,但后来又出现了另一个问题。它不会停留在字符串的内容(fread)。那么如何实现\0在字符串末尾终止?源代码:

fread
  • 如果此帖子被视为重复或违反任何其他网站规则,请发表评论并将其删除。谢谢您的时间
  • 如果您需要任何进一步的信息,现在就让我吧。

2 个答案:

答案 0 :(得分:3)

通过评论中的大部分建议,我创建了一个文件xr71.c

#include <stdio.h>
#include <stdlib.h>

#define Xor_key 0xCF

static
void xorInput(char *in_name, char *out_name)
{
    FILE *fp1 = fopen(in_name, "rb");
    if (fp1 == NULL)
    {
        fprintf(stderr, "failed to opn file %s for reading\n", in_name);
        exit(1);
    }

    FILE *fp2 = fopen(out_name, "wb");
    if (fp2 == NULL)
    {
        fprintf(stderr, "failed to open file %s for writing\n", out_name);
        exit(1);
    }

    char buffer[1024];
    size_t nbytes;
    while ((nbytes = fread(buffer, 1, sizeof(buffer), fp1)) > 0)
    {
        for (size_t i = 0; i < nbytes; ++i)
            buffer[i] ^= Xor_key;
        if (fwrite(buffer, 1, nbytes, fp2) != nbytes)
        {
            fprintf(stderr, "failed to write %zu bytes to %s\n", nbytes, out_name);
            exit(1);
        }
    }

    fclose(fp1);    // Error check omitted
    fclose(fp2);    // Error check omitted
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        fprintf(stderr, "Usage: %s file_name file_output_name\n", argv[0]);
        exit(1);
    }
    xorInput(argv[1], argv[2]);

    return 0;
}

请注意,所有错误消息都会写入标准错误。 static因为我使用的编译选项而存在(见下文)。公共函数必须在定义之前声明;所有函数必须在使用前声明或定义 - main()唯一例外。

编译和测试:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
>     -Wstrict-prototypes -Wold-style-definition xr71.c -o xr71  
$ ./xr71 xr71 xr71.v1
$ ./xr71 xr71.v1 xr71.v2
$ cmp xr71 xr71.v2
$ cmp xr71.v1 xr71.v2
xr71.v1 xr71.v2 differ: char 1, line 1
$ cmp -l xr71.v1 xr71.v2
   1   0 317
   2  65 372
   3  42 355
…
9034 252 145
9035 275 162
9036 317   0
$ ./xr71
Usage: xr71 file_name file_output_name
$ ./xr71 in
Usage: ./xr71 file_name file_output_name
$ ./xr71 in out err
Usage: ./xr71 file_name file_output_name
$

这是应该预料到的。输出文件xr71.v1与输入文件不同(这是好的;否则不会加密)。输出文件xr71.v2与原始输入文件(xr71)相同,这是好的;加密和解密可以让您重新开始使用。

答案 1 :(得分:3)

唯一正在进行的加密/解密是使用密钥进行异或 - 或每个字节。

不需要缓冲区(除了它可能有助于提高性能)。无需查找行尾和空字符。只需读取1个字节^,然后再写入。重复unitl已读取所有数据。

void xorInput(const char *in, const char *o) {
  FILE *fp = fopen(in, "rb");
  if (fp==NULL) {
    printf("file '%s' isn't here...\n", in);
    exit(1);
  }
  // Open in binary
  FILE *fp2 = fopen(o,"wb");
  if (fp2==NULL) {
    fclose(in);
    printf("file '%s' isn't here...\n", o);
    exit(1);
  }

  int ch;
  while ((ch = fgetc(fp)) != EOF) {
    ch ^= Xor_key;
    fputc(ch, fp2);
  }

  fclose(fp);
  fclose(fp2);
}