我想异或一个非常大的文件(~50 Go)。
更准确地说,我想通过使用密钥 3847611839 对纯文本文件的每个 32 字节块(因为内存不足)进行异或操作,并创建(一个接一个块)一个新的密码文件。
感谢您的任何帮助!!
这听起来很有趣,听起来不像是家庭作业。
我没有以前的异或加密文件可供尝试,但如果你来回转换一个,就没有差异。
我至少试过了。享受!:) 这个异或每 4 个字节带有 0xE555E5BF,我想这就是你想要的。
这是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;
}
正如starblue 在评论中提到的那样,“请注意,这充其量只是混淆,而不是加密”。它甚至可能不是混淆。
XOR 的一个属性是(Y xor 0) == Y
. 这对您的算法意味着什么,对于您非常大的文件中存在零运行的任何地方(考虑到文件的大小,这似乎很可能),您的密钥将显示在密码文件中。平淡如日。
XOR 加密内容的另一个不错的功能是,如果某人同时拥有明文和密文,则将这些项进行异或运算会为您提供一个输出,该输出具有用于反复执行密码的密钥。如果该人知道这两个文件是明文/密文对,那么他们就知道了密钥,如果该密钥用于多个加密,则该密钥是错误的。如果攻击者不确定明文和密文是否相关,那么他们在这之后会有一个很好的主意,因为密钥是输出中的重复模式。这都不是一次性密码的问题,因为密钥的每一位只使用一次,所以人们可以从这次攻击中学到任何新东西。
很多人错误地认为,因为一次性密码被证明是牢不可破的,所以 XOR 加密“如果做得好”可能是可以的,因为执行的基本操作是相同的。不同之处在于一次性键盘仅使用密钥的每个随机位一次。因此,除其他事项外,如果明文中有一系列零,则与简单的固定密钥 XOR 密码不同,对密钥一无所知。
正如布鲁斯·施奈尔(Bruce Schneier)所说:“这个世界上有两种密码学:会阻止您的小妹妹阅读您的文件的密码学,以及会阻止主要政府读取您的文件的密码学。”
XOR 密码几乎不能证明小姐妹 - 即使这样。
您需要围绕流式架构设计一个解决方案:您在“流”中读取输入文件,对其进行修改,然后将结果写入输出文件。
这样,您不必一次读取所有文件。
如果您的问题是如何在不使用磁盘上额外空间的情况下执行此操作,我会以 32 字节的倍数(尽可能大)读取块,使用内存中的块,然后再次将其写出。您应该能够使用ftell
andfseek
函数来做到这一点(long
当然,假设您的类型足够大)。
如果您可以从地址空间中节省出那么多(并且您的操作系统支持它),那么对文件进行内存映射可能会更快,但我会先尝试最简单的解决方案。
当然,如果空间不是问题,只需读取块并将它们写入一个新文件,如下所示(伪代码):
open infile
open outfile
while not end of infile:
read chunk from file
change chunk
write chunk to outfile
close outfile
close infile
这种读/处理/写是非常基本的东西。如果您有更复杂的要求,您应该用它们更新您的问题。