C 一个非常大的文件上的XOR
我想对一个非常大的文件进行异或运算(~50 Go) 更准确地说,我希望通过使用密钥3847611839对明文文件的每个32字节块(由于内存不足)进行XORing,并创建(一块接一块)一个新的密码文件C 一个非常大的文件上的XOR,c,file,io,stream,xor,C,File,Io,Stream,Xor,我想对一个非常大的文件进行异或运算(~50 Go) 更准确地说,我希望通过使用密钥3847611839对明文文件的每个32字节块(由于内存不足)进行XORing,并创建(一块接一块)一个新的密码文件 谢谢你的帮助 您需要围绕流式体系结构设计一个解决方案:在“stream”中读取输入文件,修改它,然后将结果写入输出文件 这样,您就不必一次读取所有文件。如果您的问题是如何在不使用额外磁盘空间的情况下执行此操作,我只需以32字节的倍数(尽可能大)读入数据块,在内存中处理数据块,然后再将其写入。您应该能
谢谢你的帮助 您需要围绕流式体系结构设计一个解决方案:在“stream”中读取输入文件,修改它,然后将结果写入输出文件
这样,您就不必一次读取所有文件。如果您的问题是如何在不使用额外磁盘空间的情况下执行此操作,我只需以32字节的倍数(尽可能大)读入数据块,在内存中处理数据块,然后再将其写入。您应该能够使用
ftell
和fseek
函数来实现这一点(当然,假设您的long
类型足够大)
如果您可以从地址空间(并且您的操作系统支持)中腾出那么多空间,那么内存映射文件可能会更快,但我会先尝试最简单的解决方案
当然,如果空间不是问题,只需读入块并将其写入一个新文件,如下所示(伪代码):
这种读/处理/写是非常基本的东西。如果你有更复杂的要求,你应该用它们更新你的问题。这听起来很有趣,听起来不像是家庭作业 我没有一个以前用xor加密过的文件可以尝试,但是如果你前后转换一个,就没有什么区别了 我至少试过了。享受!:)这个xor每4个字节有0xE55E5BF,我想这就是你想要的 这是bloxor.c
// bloxor.c - by Peter Boström 2009, public domain, use as you see fit. :)
#include <stdio.h>
unsigned int xormask = 0xE555E5BF; //3847611839 in hex.
int main(int argc, char *argv[])
{
printf("%x\n", xormask);
if(argc < 3)
{
printf("usage: bloxor 'file' 'outfile'\n");
return -1;
}
FILE *in = fopen(argv[1], "rb");
if(in == NULL)
{
printf("Cannot open: %s", argv[2]);
return -1;
}
FILE *out = fopen(argv[2], "wb");
if(out == NULL)
{
fclose(in);
printf("unable to open '%s' for writing.",argv[2]);
return -1;
}
char buffer[1024]; //presuming 1024 is a good block size, I dunno...
int count;
while(count = fread(buffer, 1, 1024, in))
{
int i;
int end = count/4;
if(count % 4)
++end;
for(i = 0;i < end; ++i)
{
((unsigned int *)buffer)[i] ^= xormask;
}
if(fwrite(buffer, 1, count, out) != count)
{
fclose(in);
fclose(out);
printf("cannot write, disk full?\n");
return -1;
}
}
fclose(in);
fclose(out);
return 0;
}
//bloxor.c-作者:Peter Boström 2009,公共领域,根据需要使用:
#包括
无符号整数xormask=0xE55E5BF//3847611839英寸,十六进制。
int main(int argc,char*argv[])
{
printf(“%x\n”,xormask);
如果(argc<3)
{
printf(“用法:bloxor'文件''outfile'\n”);
返回-1;
}
文件*in=fopen(argv[1],“rb”);
if(in==NULL)
{
printf(“无法打开:%s”,argv[2]);
返回-1;
}
文件*out=fopen(argv[2],“wb”);
if(out==NULL)
{
fclose(in);
printf(“无法打开“%s”进行写入。”,argv[2]);
返回-1;
}
字符缓冲区[1024];//假设1024是一个很好的块大小,我不知道。。。
整数计数;
而(计数=fread(缓冲区,1024,英寸))
{
int i;
int end=计数/4;
如果(计数%4)
++结束;
对于(i=0;i
正如starblue在评论中提到的,“请注意,这充其量只是混淆,而不是加密”。这甚至可能不是混淆
XOR的一个属性是(yXOR 0)=Y
。这对您的算法意味着,对于非常大的文件中有零运行的任何位置(考虑到文件的大小,这似乎很有可能),您的密钥将显示在密码文件中。平淡如白昼
XOR加密内容的另一个很好的特性是,如果有人同时拥有明文和密文,那么将这些项XOR在一起可以得到一个输出,该输出具有用于反复执行密码的密钥。如果此人知道这两个文件是明文/密文对,则他们已学习了密钥,如果密钥用于多个加密,则该密钥无效。如果攻击者不确定明文和密文是否相关,那么在这之后他们会有一个很好的想法,因为密钥是输出中的重复模式。所有这些都不是一次性键盘的问题,因为每个按键位只使用一次,所以一个人可以从这次攻击中学到任何新的东西
很多人错误地认为,由于一次性pad是可证明不可破解的,所以“如果做得好”,XOR加密可能是可以的,因为执行的基本操作是相同的。不同之处在于,一次性键盘只使用键的每个随机位一次。因此,除其他外,如果明文中有一系列的零,则与简单的固定密钥异或密码不同,对密钥没有任何了解
正如布鲁斯·施奈尔(Bruce Schneier)所说:“这个世界上有两种密码学:一种是阻止你妹妹阅读你的文件的密码学,另一种是阻止主要政府阅读你的文件的密码学。”
XOR密码几乎不能证明是妹妹式的——即使是这样。我在这里引用自己的话:“如果你没有使用“?”,那么你可能应该重新思考你的问题):-你在问什么?请注意,这充其量只是混淆,而不是加密。由于内存不足,你只能以32字节的块进行处理?真正地是什么对可用内存施加了如此严格的限制?他的意思是他无法将整个内容读入内存,对其进行异或运算并将其保存回去。我不会将32个字节确切地称为“块”。当文件长度不是4的倍数时,文件中的最后一个字节会发生什么情况?:)哇!你的代码是完美的。非常感谢!但是我不明白这行:for(I=0;I
// bloxor.c - by Peter Boström 2009, public domain, use as you see fit. :)
#include <stdio.h>
unsigned int xormask = 0xE555E5BF; //3847611839 in hex.
int main(int argc, char *argv[])
{
printf("%x\n", xormask);
if(argc < 3)
{
printf("usage: bloxor 'file' 'outfile'\n");
return -1;
}
FILE *in = fopen(argv[1], "rb");
if(in == NULL)
{
printf("Cannot open: %s", argv[2]);
return -1;
}
FILE *out = fopen(argv[2], "wb");
if(out == NULL)
{
fclose(in);
printf("unable to open '%s' for writing.",argv[2]);
return -1;
}
char buffer[1024]; //presuming 1024 is a good block size, I dunno...
int count;
while(count = fread(buffer, 1, 1024, in))
{
int i;
int end = count/4;
if(count % 4)
++end;
for(i = 0;i < end; ++i)
{
((unsigned int *)buffer)[i] ^= xormask;
}
if(fwrite(buffer, 1, count, out) != count)
{
fclose(in);
fclose(out);
printf("cannot write, disk full?\n");
return -1;
}
}
fclose(in);
fclose(out);
return 0;
}