Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C中对文件缓冲区进行异或运算并输出到新文件_C_File_Encryption - Fatal编程技术网

如何在C中对文件缓冲区进行异或运算并输出到新文件

如何在C中对文件缓冲区进行异或运算并输出到新文件,c,file,encryption,C,File,Encryption,为什么我的输出包含额外的字符?为什么只有通过notepad++加密的每个文件的第一行,而不是整个文件? 快乐编码! 我有Kernighan和Ritchie的第二版C编程语言 编辑:这个代码是我修复后的代码,问题已经回答了。谢谢你们 以下是我的源代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #define getchar() getc(stdin) #define putchar()

为什么我的输出包含额外的字符?为什么只有通过notepad++加密的每个文件的第一行,而不是整个文件? 快乐编码! 我有Kernighan和Ritchie的第二版C编程语言

编辑:这个代码是我修复后的代码,问题已经回答了。谢谢你们

以下是我的源代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define getchar() getc(stdin)
#define putchar() putc((c),stdout)
#define XOR_BYTE 0x9E

char * xorBuffer(char *buffer, long bufferSize){

    int i;
    for(i = 0;i <= bufferSize;i++){
        buffer[i] ^= XOR_BYTE;
    }
    return buffer;
}

int xorFile(char *fileIn, char * fileOut){

    FILE *fpi, *fpo;
    char *fileBuffer = NULL;

    fpi = fopen(fileIn,"rb");
    fpo = fopen(fileOut,"wb");

    if(NULL == fpi){
        printf("Error opening input file %s: %s\n", fileIn, strerror(errno));
        return 1;
    }
    if(NULL == fpo){
        printf("Error opening output file %s: %s\n", fileOut, strerror(errno));
        return 2;
    }

    fseek(fpi,0L,SEEK_END);
    long fileSize = ftell(fpi); 
    fileBuffer = malloc(sizeof(char)* (fileSize + 1));  
    fseek(fpi,0L,SEEK_SET);     
    size_t length = fread(fileBuffer, sizeof(char), fileSize,fpi);      
    fileBuffer[length];
    fileBuffer = (char *)xorBuffer(fileBuffer,fileSize);    
    int c;  
    for(c = 0;c < fileSize;c++){ 
        putc(((fileBuffer[c])),fpo);
    }

    fclose(fpi);
    fclose(fpo);
    free(fileBuffer);
    return 0;
}

int main(int argc, char*argv[]){
    if(argc == 3){
        if(xorFile(argv[1],argv[2]) == 0)
            printf("File encryption was successful.");
        else
            printf("An error occured.");
    }else{
        printf("usage --- xor [input file][output file]");
    }
}
#包括
#包括
#包括
#定义getchar()getc(stdin)
#定义putchar()putc((c),stdout)
#定义XOR_字节0x9E
char*xorBuffer(char*buffer,long bufferSize){
int i;

对于(i=0;i您正在将字符串传递到一个需要FILE*参数的函数中。这告诉我编译器在抱怨您,而您却忽略了它

此外,您也没有测试fopen函数的任何返回值


因此,修复这两个问题,然后重新发布
XOR\u文件的原型是不正确的:您应该使用两个字符串

您的代码中还有更多问题:

  • 你必须学会缩进你的代码并明智地使用空格。使用书中所示的Kernighan和Ritchie风格
  • 使用
    fseek
    ftell
    无法可靠地获得文件大小,通常不需要它,您可以使用固定大小的缓冲区实现缓冲版本
  • 避免覆盖程序中的输入文件。如果出错,它将丢失
  • 您不需要空终止读取文件的数组,只需迭代所有字节,但在读取的大小处停止:使用
    for(i=0;i
    否则在加密时会输出一个额外字节,在解密时会再输出一个字节
  • XOR\u BUFFER(char*FILE\u BUFFER)
    中的
    '\0'
    传递大小并使用它之前,不要迭代。否则将无法加密包含空字节的二进制文件
  • 您忘了用
    fclose(fpo);
  • 不要重新定义标准函数,例如
    getchar()
    putchar()
  • 不要对函数名和/或变量名使用大写字母,但对宏使用大写字母确实是常见的做法
以下是一个简化版本:

#include <stdio.h>
#include <string.h>
#include <errno.h>

#define XOR_BYTE   0x9E

int xor_file(const char *infile, const char *outfile) {
    FILE *fpi, *fpo;
    int c;

    if ((fpi = fopen(infile, "rb")) == NULL) {
        fprintf("cannot open input file %s: %s\n", infile, strerror(errno));
        return 1;
    }
    if ((fpo = fopen(outfile, "wb")) == NULL) 
        fprintf("cannot open output file %s: %s\n", outfile, strerror(errno));
        fclose(fpi);
        return 2;
    }

    while ((c = getc(fpi)) != EOF) {
        putc(c ^ XOR_BYTE, fpo);
    }
    fclose(fpi);
    fclose(fpo);
    return 0;
}

int main(int argc, char *argv[]) {      
    if (argc == 3) {
        xor_file(argv[1], argv[2]);
    } else {
        fprintf(stderr, "usage: xor_file input_file output_file\n");
    }
    //getch();  // avoid the need for this by running your program in the terminal
    return 0;
}
#包括
#包括
#包括
#定义XOR_字节0x9E
int xor_文件(常量字符*填充,常量字符*输出文件){
文件*fpi,*fpo;
INTC;
if((fpi=fopen(infle,“rb”))==NULL){
fprintf(“无法打开输入文件%s:%s\n”,infle,strerror(errno));
返回1;
}
if((fpo=fopen(outfile,“wb”))==NULL)
fprintf(“无法打开输出文件%s:%s\n”,输出文件,strerror(errno));
fclose(fpi);
返回2;
}
而((c=getc(fpi))!=EOF){
putc(c^XOR_字节,fpo);
}
fclose(fpi);
fclose(fpo);
返回0;
}
intmain(intargc,char*argv[]){
如果(argc==3){
xor_文件(argv[1],argv[2]);
}否则{
fprintf(stderr,“用法:xor_文件输入_文件输出_文件\n”);
}
//getch();//通过在终端中运行程序来避免这种需要
返回0;
}

请参阅。无意冒犯,但我们对您的历史记录不感兴趣。请发布回答您问题所需的相关信息。如果您对安全感兴趣,请首先关注编译器消息。然后思考您实际编写的内容,例如
文件缓冲区[i]是什么!='\0'
test以及您为什么要测试它?请正确格式化您的代码。对您的样式的一些注释:1.仅将所有大写字母用于常量-这是一种不成文的规则。2.不要将stderr用于“normal”输入/输出。它用于错误消息,因此名为。3.毕竟,“\0”作为结束标记可能不是一个好主意-您的文件可能包含该字符。您已经分配了该缓冲区,并且缓冲区中有一个字符的字节计数-为什么不使用它?4.永远,永远,在没有正确关联的free()的情况下使用malloc()5.如果输入和输出文件名相同,会发生什么情况?想想看……6.文件已经被提到。@M.M我非常感谢你的评论……这一切都说明了为什么我只得到了一行xor'd。这是一条评论,而不是一个答案。@pm100感谢很多人马上为我指出了正确的方向!这也是我的一个想法我真的很感激,伙计,你们都很摇滚,我只是重新定义了getchar()和putchar(),因为它是用“C编程语言”完成的作者Richtie和Kernighan的书,那么这样做实际上是不好的做法吗?你能不能在你的第二份公告中详细说明一下?@JoshGolden:
getchar()
putchar()
是在
中定义的标准函数/宏,K&R演示了C语言书中的宏功能,但您不应该在自己的代码中重新定义这些函数/宏。@JoshGolden:在上面的代码中,我验证了命令行参数的数量,将文件名传递给
xor\U文件()
,打开文件,检查是否成功,然后运行一个非常简单的循环,一次读取一个字节,然后将xor'ed值写入输出文件。是的,我理解了您所说的代码,我只是想知道如何使用fseek和ftell获得文件的大小。