Как выполнять побитовые операции с файлами в linux?
Я хочу сделать некоторые побитовые операции (например, xor два файла) на файлах в Linux , и я понятия не имею, как это сделать. Есть приказ или нет?
любая помощь будет оценили.
3 ответов
вы можете сопоставить файл с 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;
}
быстрый поиск в интернете показал,Монолит, выделенная программа с открытым исходным кодом для XORing двух файлов. Я нашел его, потому что Брюс Шнайер написал об этом в блоге, и цели этого, похоже, имеют юридическую природу.
благодаря "phihag" этот код предназначен для выполнения двоичных операций над 2 файлами.
Бывший.1: у вас есть два файла и вы хотите сравнить эти два, поэтому вы делаете двоичный XOR на них.
Бывший.2: вы загрузили файл с помощью jdownloader или sth, и вы переместили незавершенную загрузку в другую папку, а затем менеджер загрузки продолжает незавершенные части и создает другой файл. Таким образом, у вас есть два отдельных файла, которые могут дополнять друг друга. Теперь, если вы делаете двоичный файл или на этих двух файлы у вас есть полный файл.
предупреждение: больший файл будет перезаписан с результатом операции.
#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;
}