비트 OR 2개 바이너리 파일

비트 OR 2개 바이너리 파일

나는 얼마 전에 죽어가는 HDD에 대해 2번의 구조 시도를 했습니다. 먼저 (GNU)를 실행 ddrescue한 다음 dd직접 수동 탐색을 실행했습니다. 두 이미지의 장점을 최대한 활용하고 싶습니다. 파일의 빈 확장은 모두 0이므로 두 파일을 병합하려면 비트 AND로 충분해야 합니다.

두 입력 파일의 OR인 파일을 생성할 수 있는 유틸리티가 있습니까?

(저는 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

파이썬

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개의 부분 토렌트 파일을 성공적으로 병합)에서 작동하는 것으로 보이지만 철저하게 테스트되지 않았습니다.

아마도 if ...: break패턴을 제거하고 대신 사용할 수 있습니다.while in1 or in2:

답변3

이것은 비트별 or가 아니지만 0(전체 블록)에 대해 작동합니다.

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

이로 인해 sparse소스 파일에 0인 항목 쓰기를 건너뜁니다.

따라서 baz는 bar처럼 보일 것이며 bar에서는 0이지만 foo에서는 0이 아닌 모든 것을 더한 것입니다.

즉, foo와 bar에 동일하지 않은 0이 아닌 데이터가 있으면 bar가 승리합니다.

관련 정보