按位或 2 個二進位文件

按位或 2 個二進位文件

不久前,我對一個快要死的硬碟進行了兩次救援嘗試;我先運行(GNU)ddrescue,然後直接dd手動查找。我想充分利用這兩個圖像。由於文件中的任何空部分都只是 0,因此按位與應該足以合併兩個文件。

是否有一個實用程式允許我建立一個文件,該文件是兩個輸入文件的或?

(我正在使用 ArchLinux,但如果它不在儲存庫中,我很樂意從原始程式碼安裝)

答案1

我不知道有什麼實用程式可以做到這一點,但編寫一個程式來做到這一點應該很容易。這是一個 Python 的骨架範例:

#!/usr/bin/env python
f=open("/path/to/image1","rb")
g=open("/path/to/image2","rb")
h=open("/path/to/imageMerge","wb") #Output file
while True:
     data1=f.read(1) #Read a byte
     data2=g.read(1) #Read a byte
     if (data1 and data2): #Check that neither file has ended
          h.write(chr(ord(data1) | ord(data2))) #Or the bytes
     elif (data1): #If image1 is longer, clean up
          h.write(data1) 
          data1=f.read()
          h.write(data1)
          break
     elif (data2): #If image2 is longer, clean up
          h.write(data2)
          data2=g.read()
          h.write(data2)
          break
     else: #No cleanup needed if images are same length
          break
f.close()
g.close() 
h.close()

或一個應該運行得更快的 C 程式(但更有可能出現未被注意到的錯誤):

#include <stdio.h>
#include <string.h>

#define BS 1024

int main() {
    FILE *f1,*f2,*fout;
    size_t bs1,bs2;
    f1=fopen("image1","r");
    f2=fopen("image2","r");
    fout=fopen("imageMerge","w");
    if(!(f1 && f2 && fout))
        return 1;
    char buffer1[BS];
    char buffer2[BS];
    char bufferout[BS];
    while(1) {
        bs1=fread(buffer1,1,BS,f1); //Read files to buffers, BS bytes at a time
        bs2=fread(buffer2,1,BS,f2);
        size_t x;
        for(x=0;bs1 && bs2;--bs1,--bs2,++x) //If we have data in both, 
            bufferout[x]=buffer1[x] | buffer2[x]; //write OR of the two to output buffer
        memcpy(bufferout+x,buffer1+x,bs1); //If bs1 is longer, copy the rest to the output buffer
        memcpy(bufferout+x,buffer2+x,bs2); //If bs2 is longer, copy the rest to the output buffer
        x+=bs1+bs2;
        fwrite(bufferout,1,x,fout);
        if(x!=BS)
            break;
    }
}

答案2

Python

with open('file1', 'rb') as in1, open('file2', 'rb') as in2, open('outfile', 'wb') as out:
    while True:
        bytes1 = in1.read(1024)
        bytes2 = in2.read(1024)
        if not bytes1 or not bytes2:
            break
        out.write(bytes(b1 | b2 for (b1, b2) in zip(bytes1, bytes2)))

由於一次讀取 1024 個字節,這比 Chris 的 Python 解決方案快大約 10 倍。它還使用該with open模式,因為這在關閉文件時更可靠(例如,在發生錯誤的情況下)。

這似乎對我來說適用於 Python 3.6.3(成功合併 2 個部分 torrent 檔案),但尚未經過徹底測試。

if ...: break也許可以刪除該模式並改為使用while in1 or in2:

答案3

這不是按位或,但它適用於(整塊)零:

dd conv=sparse,notrunc if=foo of=baz
dd conv=sparse,notrunc if=bar of=baz

由於sparse它會跳過在來源文件中寫入任何零的內容。

所以 baz 看起來會像 bar,加上 bar 中為零但 foo 中不為零的內容。

換句話說,如果 foo 和 bar 中存在不相同的非零數據,則 bar 獲勝。

相關內容