如何对linux中的文件执行按位操作?

时间:2011-07-31 11:06:51

标签: c++ linux command bitwise-operators

我想在Linux上对文件执行一些按位操作(例如xor两个文件),我不知道如何做到这一点。是否有任何命令?

任何帮助将不胜感激。

3 个答案:

答案 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;
}