我想在Linux上对文件执行一些按位操作(例如xor两个文件),我不知道如何做到这一点。是否有任何命令?
任何帮助将不胜感激。
答案 0 :(得分:9)
您可以使用mmap映射文件,对映射的内存应用按位操作,然后将其关闭。
或者,将块读入缓冲区,对缓冲区应用操作,并写出缓冲区也可以。
这是一个例子(C,而不是C ++;因为除错误处理之外的所有内容都是相同的)反转所有位:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
int main(int argc, char* argv[]) {
if (argc != 2) {printf("Usage: %s file\n", argv[0]); exit(1);}
int fd = open(argv[1], O_RDWR);
if (fd == -1) {perror("Error opening file for writing"); exit(2);}
struct stat st;
if (fstat(fd, &st) == -1) {perror("Can't determine file size"); exit(3);}
char* file = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if (file == MAP_FAILED) {
perror("Can't map file");
exit(4);
}
for (ssize_t i = 0;i < st.st_size;i++) {
/* Binary operation goes here.
If speed is an issue, you may want to do it on a 32 or 64 bit value at
once, and handle any remaining bytes in special code. */
file[i] = ~file[i];
}
munmap(file, st.st_size);
close(fd);
return 0;
}
答案 1 :(得分:2)
快速互联网搜索显示Monolith,这是一个专门的开源程序,用于对两个文件进行异或。我发现它是因为Bruce Schneier在博客上发表了这篇文章,其目的似乎具有法律性质。
答案 2 :(得分:2)
感谢“phihag”,这段代码用于对2个文件进行二进制操作
例1:你有两个文件,想要比较这两个文件,所以你对它们进行二进制异或。
例2:您已经下载了一个带有jdownloader或类似的文件,并且您已将未完成的下载移动到另一个文件夹,然后下载管理器继续未完成的部分并创建另一个文件。所以你有两个seprate文件可以互相完成。现在,如果您对这两个文件执行二进制OR,则您有一个完整的文件。
警告:较大的文件将被操作结果覆盖。
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
int main(int argc, char* argv[])
{
int FP1 = 0, FP2 = 0;
struct stat St1, St2;
char *File1 = NULL, *File2 = NULL;
int Rn = 0;
if (argc != 4)
{
printf("Usage: %s File1 File2 Operator\n", argv[0]);
exit(1);
}
//Opening and mapping File1
FP1 = open(argv[1], O_RDWR);
if (FP1 == -1)
{
perror("Error opening file1 for writing");
exit(2);
}
if (fstat(FP1, &St1) == -1)
{
perror("Can't determine file1 size");
exit(3);
}
File1 = (char*) mmap(NULL, St1.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, FP1, 0);
if (File1 == MAP_FAILED)
{
perror("Can't map file1");
exit(4);
}
//======================
//Opening and mapping File2
FP2 = open(argv[2], O_RDWR);
if (FP2 == -1)
{
perror("Error opening file2 for writing");
exit(2);
}
if (fstat(FP2, &St2) == -1)
{
perror("Can't determine file2 size");
exit(3);
}
File2 = (char*) mmap(NULL, St2.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, FP2, 0);
if (File2 == MAP_FAILED)
{
perror("Can't map file2");
exit(4);
}
//======================
//Binary operations
ssize_t i = 0;
switch (*(argv[3]))
{
case '|':
if (St1.st_size <= St2.st_size)
for (i = 0; i < St1.st_size; i ++)
File2[i] = File1[i] | File2[i];
else
for (i = 0; i < St2.st_size; i ++)
File1[i] = File1[i] | File2[i];
break;
case '&':
if (St1.st_size <= St2.st_size)
for (i = 0; i < St1.st_size; i ++)
File2[i] = File1[i] & File2[i];
else
for (i = 0; i < St2.st_size; i ++)
File1[i] = File1[i] & File2[i];
break;
case '^':
if (St1.st_size <= St2.st_size)
for (i = 0; i < St1.st_size; i ++)
File2[i] = File1[i] ^ File2[i];
else
for (i = 0; i < St2.st_size; i ++)
File1[i] = File1[i] ^ File2[i];
break;
default:
perror("Unknown binary operator");
exit(5);
}
//======================
munmap(File1, St1.st_size);
munmap(File2, St2.st_size);
close(FP1);
close(FP2);
//Renaming the changed file and make output
char Buffer[1024];
if (St1.st_size <= St2.st_size)
{
Rn = system(strcat(strcat(strcat(strcat(strcpy(Buffer, "mv \""), argv[2]), "\" \""), argv[2]),"-Mapped\""));
if (Rn == -1)
{
perror("Unable to rename the new file.");
exit(6);
}
else
printf("%s is mapped.\n", argv[2]);
}
else
{
Rn = system(strcat(strcat(strcat(strcat(strcpy(Buffer, "mv \""), argv[1]), "\" \""), argv[1]),"-Mapped\""));
if (Rn == -1)
{
perror("Unable to rename the new file.");
exit(6);
}
else
printf("%s is mapped.\n", argv[1]);
}
//======================
return 0;
}