วิธีเปรียบเทียบไฟล์ไบนารีเพื่อตรวจสอบว่าเหมือนกันหรือไม่


186

อะไรคือวิธีที่ง่ายที่สุด (ใช้เครื่องมือกราฟิกหรือบรรทัดคำสั่งบน Ubuntu Linux) เพื่อทราบว่าไฟล์ไบนารีสองไฟล์เหมือนกันหรือไม่ (ยกเว้นการประทับเวลา) ฉันไม่จำเป็นต้องแยกความแตกต่างจริง ๆ ฉันแค่ต้องรู้ว่าพวกเขาเหมือนกันหรือไม่


5
คำถามที่ถามเพื่อแสดงให้เห็นถึงความแตกต่าง: superuser.com/questions/125376/…
Ciro Santilli 法轮功冠状病病六四事件法轮功

2
หน้า man สำหรับcmpบอกว่ามันทำการเปรียบเทียบ byte byte เป็นค่าเริ่มต้นของฉันสำหรับไฟล์ไบนารี 2 ไฟล์ diffเป็นบรรทัดต่อบรรทัดและจะให้คำตอบใช่ / ไม่ใช่เดียวกัน แต่แน่นอนไม่ใช่การถ่ายโอนข้อมูลเดียวกันกับสตรีมออกมาตรฐาน cmpถ้าเส้นมีความยาวเพราะบางทีพวกเขาไม่ได้เป็นไฟล์ข้อความแล้วฉันต้องการ diffมีข้อได้เปรียบที่คุณสามารถระบุการเปรียบเทียบของไดเรกทอรีและ-rสำหรับการสอบถามซ้ำดังนั้นการเปรียบเทียบหลายไฟล์ในคำสั่งเดียว
H2ONaCl

คำตอบ:


180

ยูนิกซ์มาตรฐานdiffจะแสดงว่าไฟล์เหมือนกันหรือไม่:

[me@host ~]$ diff 1.bin 2.bin
Binary files 1.bin and 2.bin differ

หากไม่มีเอาต์พุตจากคำสั่งหมายความว่าไฟล์ไม่มีความแตกต่าง


5
diff ดูเหมือนว่าจะมีปัญหากับไฟล์ที่มีขนาดใหญ่จริงๆ ฉันได้รับdiff: memory exhaustedเมื่อเปรียบเทียบไฟล์ 13G สองไฟล์
Yongwei Wu

1
ผลผลิตที่น่าสนใจ diffกำลังบอกคุณว่าพวกเขาเป็น "binary" fies เนื่องจากไฟล์ทั้งหมดถือได้ว่าเป็นไบนารีซึ่งเป็นการยืนยันที่แปลก
H2ONaCl

7
คุณสามารถรายงานไฟล์ที่เหมือนกันพร้อมตัวเลือก: diff -s 1.bin 2.binหรือdiff --report-identical-files 1.bin 2.binรายการนี้Files 1.bin and 2.bin are identical
Tom Kuschel

1
ไม่มันจะบอกว่าพวกเขา "แตกต่าง" ดังนั้นพวกเขาจึงไม่เหมือนกัน
Josef Klimuk

1
ฉันมีสอง executables ฉันรู้ว่าพวกเขาแตกต่างกันเพราะฉันรวบรวมและวิ่งพวกเขา แต่ตัวเลือกทั้งหมดของ diff และ cmp ที่นี่ตัดสินพวกเขาเหมือนกัน ทำไม? !!!
mirkastath

107

ใช้cmpคำสั่ง สิ่งนี้จะออกอย่างหมดจดหากพวกเขามีค่าเท่ากับไบนารีหรือมันจะพิมพ์ออกมาในกรณีที่มีความแตกต่างแรกเกิดขึ้นและออก


9
สำหรับกรณีการใช้ OP อธิบาย IMHO จะมีประสิทธิภาพมากกว่าcmp diffดังนั้นฉันชอบสิ่งนี้
halloleo

5
ฉันมีเชลล์สคริปที่ทำงาน:cmp $1 $2 && echo "identical" || echo "different"
steveha

2
cmp หยุดทำงานเมื่อพบความแตกต่างแรกและแสดงหรือผ่านจุดสิ้นสุดของไฟล์
สบ

cmpมีโหมด "เงียบ": --s, --quiet, --silent suppress all normal outputฉันยังไม่ได้ทดสอบ แต่ฉันคิดว่ามันจะหยุดที่ความแตกต่างแรกถ้ามี
Victor Yarema

89

ฉันพบVisual Binary Diffเป็นสิ่งที่ฉันกำลังมองหาอยู่ใน:

  • อูบุนตู:

    sudo apt install vbindiff
    
  • Arch Linux:

    sudo pacman -S vbindiff
    
  • Mac OS X ผ่านMacPorts :

    port install vbindiff
    
  • Mac OS X ผ่าน Homebrew:

    brew install vbindiff
    

1
ดี ... ฉัน / คิด / ฉันแค่อยากจะรู้ว่าไฟล์ที่แตกต่าง; แต่ความสามารถในการเห็นความแตกต่างที่แน่นอนได้อย่างง่ายดายมีประโยชน์มากกว่า มันมีแนวโน้มที่จะ segfault เมื่อฉันถึงจุดสิ้นสุดของไฟล์ แต่ไม่เป็นไรมันยังใช้งานได้
Jeremy

2
มีการพูดสองสามครั้ง แต่นี่เป็นโปรแกรมเล็ก ๆ ที่ยอดเยี่ยม! (fyi เหมือนกันกับ homebrew)
johncip

2
นี่ควรเป็นคำตอบที่ได้รับการยอมรับเนื่องจากเป็นวิธีที่เหนือกว่าเอาต์พุตธรรมดาและไม่ช่วยเหลือของคำสั่ง diff ตามมาตรฐาน
Gearoid Murphy

1
นี่คือเครื่องมือที่ดีที่สุดสำหรับการกระจายแบบไบนารี
คาร์ล่า Camargo

17

ใช้ sha1 เพื่อสร้างการตรวจสอบ:

sha1 [FILENAME1]
sha1 [FILENAME2]

3
หากคุณมีเช็คซัมสำหรับไฟล์ใดไฟล์หนึ่งเท่านั้นสิ่งนี้จะมีประโยชน์ แต่ถ้าคุณมีทั้งไฟล์ในดิสก์สิ่งนี้ไม่จำเป็น diffและcmpทั้งคู่จะบอกคุณว่าพวกเขาต่างกันหรือไม่โดยไม่ต้องใช้ความพยายามเป็นพิเศษ
johncip

1
มันsha1sumไม่ใช่sha1หรือ
kol

2
sha1 บน NetBSD, sha1sum บน Linux
Scott Presnell

2
มีสองไฟล์ที่จะให้ผลลัพธ์เดียวกันแม้ว่าจะแตกต่างกัน: shattered.io
mik

2
SHA1 มีการชนกันของสาธารณะหนึ่งครั้ง ( shattered.io ) และอาจไม่ใช่แบบสาธารณะเช่นกัน สามารถใช้การชนกันหนึ่งครั้งเพื่อสร้างไฟล์การชนกันนับไม่ถ้วนใช้ SHA2 เพื่อการแฮชแทน
Michal Ambroz

12

ฉันลงเอยด้วยการใช้ hexdump เพื่อแปลงไฟล์ไบนารีให้เป็นเลขฐานสิบหกจากนั้นเปิดไฟล์เหล่านั้นใน meld / kompare / เครื่องมือ diff อื่น แตกต่างจากคุณฉันหลังจากที่แตกต่างในไฟล์

hexdump tmp/Circle_24.png > tmp/hex1.txt
hexdump /tmp/Circle_24.png > tmp/hex2.txt

meld tmp/hex1.txt tmp/hex2.txt

1
ใช้hexdump -v -e '/1 "%02x\n"'ถ้าคุณต้องการกระจายและดูว่ามีการแทรกหรือลบไบต์ใด
William Entriken

Meld ยังใช้งานได้กับไฟล์ไบนารีเมื่อไม่แปลงเป็น hex ก่อน มันแสดงค่าฐานสิบหกสำหรับสิ่งที่ไม่ได้อยู่ในชุดถ่านมิฉะนั้นตัวอักษรปกติซึ่งมีประโยชน์กับไฟล์ไบนารีที่มีข้อความ ASCII บางส่วน หลายคนทำอย่างน้อยเริ่มต้นด้วยสายเวทย์มนตร์
เฟลิกซ์ Dombek

7

คุณสามารถใช้ฟังก์ชันแฮช MD5 เพื่อตรวจสอบว่ามีสองไฟล์เหมือนกันหรือไม่โดยคุณไม่สามารถเห็นความแตกต่างในระดับต่ำ แต่เป็นวิธีที่รวดเร็วในการเปรียบเทียบสองไฟล์

md5 <filename1>
md5 <filename2>

หากทั้งสอง MD5 hash (เอาต์พุตคำสั่ง) เหมือนกันไฟล์ทั้งสองจะไม่ต่างกัน


7
คุณช่วยอธิบายการโหวตของคุณลงได้ไหม? SHA1 มี 4 upvotes และถ้า OP คิดว่ามีโอกาสไฟล์สองไฟล์อาจเหมือนหรือคล้ายกันโอกาสของการชนกันเล็กน้อยและไม่คุ้มกับการลงคะแนนเสียง MD5 แต่ให้ลงคะแนน SHA1 มากกว่าที่คุณได้ยินเพราะคุณควรแฮช รหัสผ่านด้วย SHA1 แทนที่จะเป็น MD5 (เป็นปัญหาที่แตกต่าง)
Rikki

2
ไม่แน่ใจเกี่ยวกับเหตุผล แต่ cmp ที่บริสุทธิ์จะมีประสิทธิภาพมากกว่าการคำนวณฟังก์ชันแฮชของไฟล์และเปรียบเทียบกับไฟล์เหล่านั้น (อย่างน้อยสำหรับ 2 ไฟล์เท่านั้น)
Paweł Szczur

1
หากทั้งสองไฟล์มีขนาดใหญ่และอยู่ในดิสก์เดียวกัน (ไม่ใช่ ssd) ตัวแปร md5 หรือ sha * อาจเร็วขึ้นเพราะดิสก์สามารถอ่านไฟล์สองไฟล์ตามลำดับซึ่งจะช่วยประหยัดการเคลื่อนไหวของหัวได้มาก
Daniel Alder

7
ฉันลงคะแนนเนื่องจากคุณโพสต์ชุดตัวเลือกเล็กน้อยของโซลูชันก่อนหน้า (ไม่ดี) เมื่อมันควรได้รับความคิดเห็น
johncip

6

ใช้คำสั่ง cmp อ้างถึงไฟล์ไบนารีและการเปรียบเทียบข้อความบังคับสำหรับข้อมูลเพิ่มเติม

cmp -b file1 file2

1
-bไม่เปรียบเทียบไฟล์ใน "โหมดไบนารี" ที่จริงแล้ว "ด้วย GNU cmpคุณสามารถใช้-bหรือ--print-bytesตัวเลือกเพื่อแสดงการแทน ASCII ของไบต์เหล่านั้นได้" นี่คือสิ่งที่ฉันพบโดยใช้ URL เป็นคู่มือที่คุณให้ไว้
Victor Yarema

Victor Yarema ฉันไม่รู้ว่าคุณหมายถึงอะไรโดย "โหมดไบนารี" cmpเป็นการเปรียบเทียบแบบไบนารีในความคิดของฉัน -bตัวเลือกเพียงพิมพ์ไบต์แรกที่แตกต่าง
H2ONaCl

4

สำหรับการค้นหาข้อบกพร่องของหน่วยความจำแฟลชฉันต้องเขียนสคริปต์นี้ซึ่งแสดงบล็อกทั้งหมด 1K ซึ่งมีความแตกต่าง (ไม่เพียง แต่บล็อกแรกเท่านั้นcmp -b)

#!/bin/sh

f1=testinput.dat
f2=testoutput.dat

size=$(stat -c%s $f1)
i=0
while [ $i -lt $size ]; do
  if ! r="`cmp -n 1024 -i $i -b $f1 $f2`"; then
    printf "%8x: %s\n" $i "$r"
  fi
  i=$(expr $i + 1024)
done

เอาท์พุท:

   2d400: testinput.dat testoutput.dat differ: byte 3, line 1 is 200 M-^@ 240 M- 
   2dc00: testinput.dat testoutput.dat differ: byte 8, line 1 is 327 M-W 127 W
   4d000: testinput.dat testoutput.dat differ: byte 37, line 1 is 270 M-8 260 M-0
   4d400: testinput.dat testoutput.dat differ: byte 19, line 1 is  46 &  44 $

คำเตือน: ฉันแฮ็คสคริปต์ใน 5 นาที ไม่สนับสนุนอาร์กิวเมนต์บรรทัดคำสั่งและไม่สนับสนุนช่องว่างในชื่อไฟล์


ฉันได้รับ "r: not found" (โดยใช้ GNU linux)
unseen_rider

@unseen_rider เปลือกไหนบรรทัดไหน? โปรดเรียกสคริปต์ที่ใช้sh -xสำหรับการแก้ไขข้อบกพร่อง
Daniel Alder

นี่คือการเรียกสคริปต์จากเทอร์มินัล บรรทัดคือ 9.
unseen_rider

@unseen_rider ฉันไม่สามารถช่วยคุณในแบบนี้ สคริปต์ก็โอเค กรุณาโพสต์แก้ปัญหาส่งออกของคุณเพื่อpastebin.com คุณสามารถดูที่นี่สิ่งที่ฉันหมายถึง: pastebin.com/8trgyF4A นอกจากนี้โปรดบอกฉันว่าผลลัพธ์ของreadlink -f $(which sh)
Daniel Alder

/bin/dashคำสั่งสุดท้ายให้ กำลังสร้างการวางบน pastebin
unseen_rider

4

แตกต่างกับตัวเลือกต่อไปนี้จะทำการเปรียบเทียบแบบไบนารีเพื่อตรวจสอบว่าไฟล์ต่างกันหรือไม่และมันจะแสดงผลหากไฟล์เหมือนกันเช่นกัน:

diff -qs {file1} {file2}

หากคุณกำลังเปรียบเทียบสองไฟล์ที่มีชื่อเดียวกันในไดเรกทอรีต่างกันคุณสามารถใช้แบบฟอร์มนี้แทน:

diff -qs {file1} --to-file={dir2}

OS X El Capitan


3

ลอง diff -s

คำตอบสั้น ๆ : รันdiffด้วย-sสวิตช์

คำตอบยาว: อ่านด้านล่าง


นี่คือตัวอย่าง เริ่มต้นด้วยการสร้างสองไฟล์ด้วยเนื้อหาไบนารีแบบสุ่ม:

$ dd if=/dev/random bs=1k count=1 of=test1.bin
1+0 records in
1+0 records out
1024 bytes (1,0 kB, 1,0 KiB) copied, 0,0100332 s, 102 kB/s

                                                                                  
$ dd if=/dev/random bs=1k count=1 of=test2.bin
1+0 records in
1+0 records out
1024 bytes (1,0 kB, 1,0 KiB) copied, 0,0102889 s, 99,5 kB/s

ตอนนี้ให้ทำสำเนาไฟล์แรก:

$ cp test1.bin copyoftest1.bin

ตอนนี้ test1.bin และ test2.bin ควรแตกต่างกัน:

$ diff test1.bin test2.bin
Binary files test1.bin and test2.bin differ

... และ test1.bin และ copyoftest1.bin ควรเหมือนกัน:

$ diff test1.bin copyoftest1.bin

แต่เดี๋ยวก่อน! ทำไมถึงไม่มีเอาต์พุต?!?

คำตอบคือ: นี่คือโดยการออกแบบ ไม่มีเอาต์พุตในไฟล์ที่เหมือนกัน

แต่มีรหัสข้อผิดพลาดที่แตกต่างกัน:

$ diff test1.bin test2.bin
Binary files test1.bin and test2.bin differ

$ echo $?
1


$ diff test1.bin copyoftest1.bin

$ echo $?
0

ตอนนี้โชคดีที่คุณไม่จำเป็นต้องตรวจสอบรหัสข้อผิดพลาดทุกครั้งเพราะคุณสามารถใช้สวิตช์-s(หรือ--report-identical-files)เพื่อทำให้ diff ต่างกันมากขึ้น:

$ diff -s test1.bin copyoftest1.bin
Files test1.bin and copyoftest1.bin are identical

2

Radiff2เป็นเครื่องมือที่ออกแบบมาเพื่อเปรียบเทียบไฟล์ไบนารีคล้ายกับ diff ทั่วไปเปรียบเทียบไฟล์ข้อความ

ลองดูradiff2ว่าส่วนใดเป็นส่วนหนึ่งของradare2disassembler ตัวอย่างเช่นด้วยคำสั่งนี้:

radiff2 -x file1.bin file2.bin

คุณได้รับการจัดรูปแบบสวยสองคอลัมน์ผลลัพธ์ที่เน้นความแตกต่าง


1

คนที่ฉันชอบโดยใช้ xxd hex-dumper จากแพ็คเกจเป็นกลุ่ม:

1) ใช้ vimdiff (ส่วนหนึ่งของกลุ่ม)

#!/bin/bash
FILE1="$1"
FILE2="$2"
vimdiff <( xxd "$FILE1" ) <( xxd "$FILE2" )

2) ใช้ diff

#!/bin/bash
FILE1=$1
FILE2=$2
diff -W 140 -y <( xxd $FILE1 ) <( xxd $FILE2 ) | colordiff | less -R -p '  \|  '

0
md5sum binary1 binary2

หาก md5sum เหมือนกันไบนารีจะเหมือนกัน

เช่น

md5sum new*
89c60189c3fa7ab5c96ae121ec43bd4a  new.txt
89c60189c3fa7ab5c96ae121ec43bd4a  new1.txt
root@TinyDistro:~# cat new*
aa55 aa55 0000 8010 7738
aa55 aa55 0000 8010 7738


root@TinyDistro:~# cat new*
aa55 aa55 000 8010 7738
aa55 aa55 0000 8010 7738
root@TinyDistro:~# md5sum new*
4a7f86919d4ac00c6206e11fca462c6f  new.txt
89c60189c3fa7ab5c96ae121ec43bd4a  new1.txt

1
ไม่มาก ความเป็นไปได้สูงเท่านั้น
sawa

ความน่าจะเป็นของความล้มเหลวคืออะไร?
Ashish

เพรียวบาง แต่แย่กว่าการใช้ตัวแปรบางอย่างdiffซึ่งไม่มีเหตุผลที่จะชอบ
sawa

คุณจะต้องเปลี่ยนแฮช MD5 เป็น SHA2 เพื่อให้คำแนะนำนี้ใช้งานได้จริง แล็ปท็อปของทุกคนสามารถวันนี้สร้างการปะทะกันใน MD5 และขึ้นอยู่กับคำนำหน้าชนกันนี้เดียว (2 ไฟล์ที่มีขนาดเดียวกันคำนำหน้าเหมือนกันและ MD5 เดียวกัน) เพื่อสร้างจำนวนอนันต์ของชนไฟล์ (มีคำนำหน้าเดียวกันบล็อกชนที่แตกต่างกันต่อท้ายเดียวกัน)
Michal Ambroz

-1

มีวิธีที่ค่อนข้างง่ายในการตรวจสอบว่าไฟล์ไบนารีสองไฟล์เหมือนกันหรือไม่

หากคุณใช้ไฟล์อินพุต / เอาต์พุตในภาษาโปรแกรม คุณสามารถเก็บแต่ละบิตของไฟล์ไบนารีทั้งสองลงในอาร์เรย์ของตัวเอง

ณ จุดนี้การตรวจสอบง่ายเหมือน:

if(file1 != file2){
    //do this
}else{
    /do that
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.