해시로 파일의 일부를 비교하는 방법?


19

하나의 파일을 성공적으로 다운로드했고 다른 파일이 같은 파일 인 것으로 의심되는 다운로드에 실패했습니다 (큰 파일의 처음 100MB 만).

이것을 확인하기 위해 해시를 확인하고 싶지만 다운로드하지 못한 파일의 일부만 가지고 있기 때문에 처음 몇 메가 바이트 정도만 해시하고 싶습니다.

어떻게해야합니까?

OS는 Windows이지만 Cygwin과 MinGW가 설치되어 있습니다.


1
로컬 컴퓨터의 한 파일과 원격 컴퓨터의 다른 파일을 효율적으로 비교하는 것은 rsync 의 핵심 부분 으로, 파일의 일부를 특수 해시 함수와 비교합니다.
David Cary

@DavidCary 내 경우, 나는 원격 컴퓨터에 쉘 액세스 할 수없는,하지만 덕분에 힌트를 위해, 나는 맨 페이지를 읽
죄를

답변:


56

파일을 비교하기 위해 해시를 작성하면 한 파일을 여러 파일과 비교하거나 많은 파일을 서로 비교할 때 의미가 있습니다.

두 파일을 한 번만 비교하는 경우에는 의미가 없습니다. 해시를 계산하려는 노력은 파일을 살펴보고 직접 비교하는 것만큼이나 높습니다.

효율적인 파일 비교 도구는 cmp다음과 같습니다.

cmp --bytes $((100 * 1024 * 1024)) file1 file2 && echo "File fragments are identical"

dd두 파일의 임의 부분 (처음부터는 아님)을 비교하기 위해 다음과 같이 결합 할 수도 있습니다 .

cmp \
    <(dd if=file1 bs=100M count=1 skip=1 2>/dev/null) \
    <(dd if=file2 bs=100M count=1 skip=1 2>/dev/null) \
&& echo "File fragments are identical"

6
참고 : 동시에 두 파일을 읽지 않으려면 파일을 비교하기 위해 해시를 작성하는 것이 좋습니다.
Kamil Maciorowski

1
@KamilMaciorowski 그렇습니다. 그러나이 방법은 일반적으로 쌍 단위의 경우 해시를 비교하는 것보다 빠릅니다.
Konrad Rudolph

8
이것이 바로 해결책입니다. 실행중인 cmp경우 이미 설치되어 있는지 99.99 % 확실 bash하며 작업을 수행합니다. 실제로, cmp -n 131072 one.zip two.zip 일도 할 것입니다. 입력하기 가장 적은 문자 및 가장 빠른 실행. 해시 계산은 의미가 없습니다. 그것은 읽을 수 있도록 전체 메가 바이트 파일이 필요 플러스 무의미 전체 파일의 100MB의 부분을. 파일이 zip 파일이고 다른 경우 처음 몇 백 바이트 내에 차이가 있습니다. Readahead는 기본적으로 128k를 제공하므로 128k를 비교할 수도 있습니다 (1 바이트 비교와 동일한 비용).
데이먼

19
--bytes옵션은 작업을 복잡하게 만듭니다. cmp이 옵션없이 실행 하면 파일간에 다른 첫 번째 바이트가 표시됩니다. 모든 바이트가 동일 EOF하면 더 짧은 파일에 표시 됩니다. 이것은 당신에게 당신의 예제보다 더 많은 정보를 줄 것입니다-얼마나 많은 바이트가 올바른지.
pabouk

2
GNU를 가지고 있다면 cmp(그리고 거의 모든 사람들이 생각하는 것처럼) 호출을 사용 --ignore-initial하여 --bytes일을 복잡하게 만드는 대신 사용 하고 인수 할 수 있습니다 dd.
Christopher Schultz

12

나는 그것을 정확하게 시도 할 수 없어서 미안하지만, 이런 식으로 작동합니다

dd if=yourfile.zip of=first100mb1.dat bs=100M count=1
dd if=yourotherfile.zip of=first100mb2.dat bs=100M count=1

그러면 두 파일 중 처음 100MB가 표시됩니다.

이제 해시를 얻으십시오.

sha256sum first100mb1.dat && sha256sum first100mb2.dat 

직접 실행할 수도 있습니다.

dd if=yourfile.zip bs=100M count=1 | sha256sum 
dd if=yourotherfile.zip bs=100M count=1 | sha256sum 

1
중간 파일없이 어떻게 dd를 sha256sum으로 파이프하는 방법이 있습니까?

1
나는 귀하의 요청에 따라 다른 방법을 추가
davidbaumann

8
해시를 만드는 이유는 무엇입니까? 파일 조각을 직접 비교하는 것보다 효율적이지 않습니다 cmp.
Konrad Rudolph

중간 코드 샘플에서 first100mb1.dat를 두 번 말합니다. 두 번째 는 first100mb 2 .dat입니까?
doppelgreener

@KonradRudolph, "왜 해시를 만드는가?" 귀하의 솔루션 (사용 cmp)이 의심의 여지없이 승자입니다. 그러나 문제를 해결하는이 방법 (해시 사용)도 실제로 문제를 해결하는 한 존재할 수 있습니다 (:
VL-80

7

모두가 이것으로 Unix / Linux 경로를 사용하는 것처럼 보이지만 Windows 표준 명령을 사용하면 두 파일을 쉽게 비교할 수 있습니다.
FC /B file file2

FC는 지금까지 만들어진 모든 Windows NT 버전에 존재합니다. 그리고 (정확히 기억한다면) DOS에도있었습니다.
조금 느리지 만 한 번 사용하는 것은 중요하지 않습니다.


6

이진 / 16 진수 diff 프로그램을 사용하여 파일을 직접 비교할 수 있습니다 vbindiff. Linux 및 Windows에서 최대 4GB의 파일을 빠르게 비교합니다.

빨간색으로 강조된 차이 (1B와 1C) 만있는 다음과 같습니다.

one                                       
0000 0000: 30 5C 72 A7 1B 6D FB FC  08 00 00 00 00 00 00 00  0\r..m.. ........  
0000 0010: 00 00 00 00                                       ....
0000 0020:
0000 0030:
0000 0040:
0000 0050:
0000 0060:
0000 0070:
0000 0080: 
0000 0090: 
0000 00A0: 

two        
0000 0000: 30 5C 72 A7 1C 6D FB FC  08 00 00 00 00 00 00 00  0\r..m.. ........  
0000 0010: 00 00 00 00                                       ....               
0000 0020: 
0000 0030:
0000 0040:
0000 0050:
0000 0060:
0000 0070:
0000 0080:
0000 0090:                                
0000 00A0:             
┌──────────────────────────────────────────────────────────────────────────────┐
Arrow keys move  F find      RET next difference  ESC quit  T move top        
C ASCII/EBCDIC   E edit file   G goto position      Q quit  B move bottom     
└──────────────────────────────────────────────────────────────────────────────┘ 

필자의 경우 파일은 zip 아카이브이므로 의미있는 텍스트가 없습니다. 해시 값을 비교하면 오류가 발생하기 쉽고 빠릅니다.
죄 :

2
ASCII 텍스트를 의미한다면 관련이 없습니다. vbindiff(및 Konrad 's cmp)는 이진 데이터를 바이트 단위로 비교합니다. 실제로 값이 충돌을 일으킬 가능성이 훨씬 더 높습니다
Xen2050

* 위의 설명에서 " 사실 HASH 값은 충돌을 경험할 가능성이 훨씬 높습니다"라고 h를 놓쳤습니다.
Xen2050

0

Bash에 대해서는 있지만 OP에는 Windows가 있다고 말합니다. Windows 솔루션을 원하거나 필요로하는 사람에게는 두 파일을 비교할 수있는 16 진 편집기 인 HxD라는 프로그램이 있습니다. 파일 크기가 다른 경우 사용 가능한 부품이 같은지 알려줍니다. 필요한 경우 현재 선택된 항목에 대해 체크섬을 실행할 수 있습니다. 무료이며 HxD 웹 사이트 에서 다운로드 할 수 있습니다 . 저자와 관련이 없으며 몇 년 동안 사용해 왔습니다.


0

cmp는 두 파일이 더 작은 파일의 길이와 동일 할 때 알려줍니다.

$ dd if=/dev/random bs=8192 count=8192 > a
8192+0 records in
8192+0 records out
67108864 bytes transferred in 0.514571 secs (130417197 bytes/sec)
$ cp a b
$ dd if=/dev/random bs=8192 count=8192 >> b 
8192+0 records in
8192+0 records out
67108864 bytes transferred in 0.512228 secs (131013601 bytes/sec)
$ cmp a b
cmp: EOF on a

cmp는 두 파일 간의 차이를 감지하기 전에 파일 a에서 EOF가 발생했음을 알려줍니다.


좋은 지적. 당신이 그것을 보지 못했다면, 이것은 pabouk이 이미 받아 들여진 대답에 대해 언급 한 것입니다.
죄를 지었다
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.