सवाल मैं लिनक्स में बाइनरी फाइलों की तुलना कैसे करूं?


मुझे दो बाइनरी फाइलों की तुलना करने और फॉर्म में आउटपुट प्राप्त करने की आवश्यकता है

<fileoffset-hex> <file1-byte-hex> <file2-byte-hex>

हर अलग बाइट के लिए। तो अगर file1.bin है

  00 90 00 11

बाइनरी रूप में और file2.bin है

  00 91 00 10

मैं कुछ ऐसा करना चाहता हूं

  00000001 90 91
  00000003 11 10

लक्ष्य को पूरा करने का सबसे आसान तरीका क्या है? मानक उपकरण? कुछ तीसरे पक्ष के उपकरण?

(ध्यान दें: cmp -l आग से मारा जाना चाहिए, यह बाइट्स के लिए ऑफसेट और ऑक्टल के लिए एक दशमलव प्रणाली का उपयोग करता है।)


258
2018-03-29 15:28


मूल


आप मूल रूप से "बाइनरी diff" की तलाश में हैं। मैं कुछ वास्तविक बदसूरत कमांडलाइन एक लाइनर के साथ कल्पना कर सकते हैं od... - quack quixote
@quack quixote: एक लाइनर के बारे में बदसूरत क्या है? ;) - Bobby
xdelta.org काफी अच्छी तरह से काम करता है। शायद यह देखने के लायक होगा। - thatjuan
क्योंकि आप जवाब नहीं दे सकते यह प्रश्न (जैसा कि आप उपयोगकर्ता नहीं हैं), मैं बंद करने के लिए मतदान कर रहा हूं। जैसा कि यहां स्पष्ट रूप से अनुरोध किया गया है, एक बाइनरी diff बिल्कुल उपयोगी नहीं है, और मुझे लगता है कि आप कुछ उपयोगी चाहते हैं, यदि आप फ़ाइल की शुरुआत में एक बाइट डालें तो सभी बाइट्स को अलग होने के रूप में चिह्नित किया जाना चाहिए? यह जानने के बिना, यह बस बहुत अस्पष्ट है। - Evan Carroll
उल्लेख नहीं है कि यह स्पष्ट रूप से कई क्षेत्रों के नियमों के खिलाफ है, यह लगभग है "प्रोग्रामिंग और सॉफ्टवेयर विकास" और आप कैसे एक उत्पाद या सिफारिश के लिए पूछ रहे हैं उपयोग एक विशिष्ट उत्पाद। - Evan Carroll


जवाब:


यह हेक्स में ऑफ़सेट और बाइट प्रिंट करेगा:

cmp -l file1.bin file2.bin | gawk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$3)}'

या करो $1-1 पहले मुद्रित ऑफ़सेट 0 पर शुरू करने के लिए।

cmp -l file1.bin file2.bin | gawk '{printf "%08X %02X %02X\n", $1-1, strtonum(0$2), strtonum(0$3)}'

दुर्भाग्य से, strtonum() GAWK के लिए विशिष्ट है, इसलिए awk-eg के अन्य संस्करणों के लिए, mawk-आपको एक ऑक्टल-टू-दशमलव रूपांतरण फ़ंक्शन का उपयोग करने की आवश्यकता होगी। उदाहरण के लिए,

cmp -l file1.bin file2.bin | mawk 'function oct2dec(oct,     dec) {for (i = 1; i <= length(oct); i++) {dec *= 8; dec += substr(oct, i, 1)}; return dec} {printf "%08X %02X %02X\n", $1, oct2dec($2), oct2dec($3)}'

पठनीयता के लिए टूटा हुआ:

cmp -l file1.bin file2.bin |
    mawk 'function oct2dec(oct,    dec) {
              for (i = 1; i <= length(oct); i++) {
                  dec *= 8;
                  dec += substr(oct, i, 1)
              };
              return dec
          }
          {
              printf "%08X %02X %02X\n", $1, oct2dec($2), oct2dec($3)
          }'

146
2018-03-29 16:30



@gertvdijk: strtonum GAWK के लिए विशिष्ट है। मेरा मानना ​​है कि उबंटू ने पहले GAWK को डिफ़ॉल्ट के रूप में इस्तेमाल किया था, लेकिन कुछ बिंदु पर स्विच किया था mawk। किसी भी मामले में, GAWK को स्थापित किया जा सकता है और डिफ़ॉल्ट पर सेट किया जा सकता है (यह भी देखें man update-alternatives)। ऐसे समाधान के लिए मेरा अद्यतन उत्तर देखें जिसके लिए आवश्यकता नहीं है strtonum। - Dennis Williamson


जैसा ~ नीम हकीम बताया:

 % xxd b1 > b1.hex
 % xxd b2 > b2.hex

और तब

 % diff b1.hex b2.hex

या

 % vimdiff b1.hex b2.hex

143
2018-03-29 16:07



बैश में: diff <(xxd b1) <(xxd b2) लेकिन ओपी (या तुम्हारा) का आउटपुट प्रारूप ओपी के लिए कहीं भी नहीं है। - Dennis Williamson
यह vimdiff के साथ है, यह लाइनों में बाइट्स रंग होगा जहां दो 'फाइल' अलग है - akira
ओह, मैंने इसके बारे में क्यों नहीं सोचा? और मुझे यकीन है कि मैंने इस तकनीक का भी अतीत में उपयोग किया है। - njd
यह मेरे लिए बहुत अच्छा काम करता है (साथ opendiff के बजाय ओएस एक्स पर vimdiff) - डिफ़ॉल्ट दृश्य xxd बाइट-बाय-बाइट की तुलना में ट्रैक पर diff इंजन को रखता है। सादे (कच्चे) हेक्स के साथ बस स्तंभ-फिट के साथ fold, diffउन फ़ाइलों में यादृच्छिक सामग्री को फोल्ड / समूह करने का प्रयास करेगा जो मैं तुलना कर रहा था। - natevw
यह आदेश बाइट एडिशन हटाने के लिए अच्छी तरह से काम नहीं करता है, क्योंकि निम्न पंक्तियों को गलत तरीके से गलत तरीके से संशोधित किया जाएगा और संशोधित किया जाएगा diff। समाधान प्रति पंक्ति 1 बाइट डालना है और प्रस्तावित के रूप में पता कॉलम को हटा देना है जॉन लॉरेंस एस्पडन तथा मुझे। - Ciro Santilli 新疆改造中心 六四事件 法轮功


प्रयत्न diff zsh / bash प्रक्रिया प्रतिस्थापन के निम्नलिखित संयोजन में और colordiff सीएलआई में:

diff -y <(xxd foo1.bin) <(xxd foo2.bin) | colordiff

कहा पे:

  • -y आपको अंतर-दर-तरफ अंतर (वैकल्पिक) दिखाता है
  • xxd बाइनरी फ़ाइल का हेक्सडम्प आउटपुट बनाने के लिए सीएलआई उपकरण है
  • colordiff रंगीन होगा diff आउटपुट (के माध्यम से स्थापित करें: sudo apt-get install colordiff)
  • जोड़ना -W200 सेवा मेरे diff व्यापक उत्पादन के लिए

संकेत:

  • अगर फाइलें बड़ी हैं, तो सीमा जोड़ें (उदा। -l1000) प्रत्येक के लिए xxd

नमूना उत्पादन:

binary file output in terminal - diff -y <(xxd foo1.bin) <(xxd foo2.bin) | colordiff


65
2017-09-05 21:14



कमांड को सरलीकृत किया जा सकता है colordiff -y <(xxd foo1.bin) <(xxd foo2.bin)। - golem
यदि आपके पास कोलोर्डिफ़ नहीं है, तो यह रंगों के बिना वही काम करेगा: diff -y <(xxd foo1.bin) <(xxd foo2.bin) - Rock Lee
यदि आप सिर्फ यह जानना चाहते हैं कि दोनों फाइलें वास्तव में समान हैं, तो आप इसका उपयोग कर सकते हैं -q या --brief स्विच, जो फाइलों को अलग करते समय केवल आउटपुट दिखाएगा। - Stefan van den Akker
एक समारोह बनाएँ xxddiff इसके लिए: xxddiff() ( f() ( xxd "$1" ; ); diff -y <(f "$1") <(f "$2") | colordiff; ) - rubo77
महान! फिर भी, diff -u <(xxd tinga.tgz) <(xxd dec.out.tinga.tgz) | vim -  एक नौकरी अच्छा enoug करेंगे - ribamar


एक उपकरण कहा जाता है DHEX जो नौकरी कर सकता है, और एक और उपकरण कहा जाता है VBinDiff

कड़ाई से कमांड लाइन दृष्टिकोण के लिए, कोशिश करें JDIFF


48
2018-03-29 15:41



डीएचएक्स भयानक है द्विआधारी की तुलना करना आप जो करना चाहते हैं वह है। इसे दो फाइलें खिलाएं और यह आपको अगले अंतर में जाने की आसान क्षमता के साथ मतभेदों को हाइलाइट करने, तुलनात्मक दृश्य के लिए सही ले जाएगा। इसके अलावा यह बड़े टर्मिनलों के साथ काम करने में सक्षम है, जो वाइडस्क्रीन मॉनीटर पर बहुत उपयोगी है। - Marcin
मैं VBinDiff पसंद करते हैं। डीएचएक्स निष्क्रिय होने पर भी सीपीयू का उपयोग कर रहा है, मुझे लगता है कि यह हर समय या कुछ वापस ले रहा है। हालांकि VBinDiff व्यापक टर्मिनलों के साथ काम नहीं करता है। लेकिन पते चौड़े टर्मिनल के साथ अजीब हो जाते हैं, क्योंकि आपके पास प्रति पंक्ति 16 बाइट से अधिक है। - Janus Troelsen
vbindiff हमें वास्तव में फ़ाइल, thx संपादित करने देता है! - Aquarius Power
पहले अलग बाइट का सामना करने के बाद @DanielBeauyat संपीड़ित फ़ाइलें पूरी तरह से अलग होंगी। आउटपुट उपयोगी होने की संभावना नहीं है। - Mark Ransom
@ 1111161171159459134 jdiff jdiff द्वारा प्राप्त मतभेदों को सिंक और पैच करने के लिए कार्यक्रमों के "सूट" का हिस्सा है। लेकिन, जैसा कि मार्क रान्ससम ने कहा था, यह आम तौर पर संकुचित फाइलों पर बुद्धिमान नहीं होगा; अपवाद "सिंक्रनाइज़ेबल" संकुचित प्रारूप है (जैसे कि gzip --rsyncable द्वारा उत्पादित), जिसमें असम्पीडित फ़ाइलों में छोटे अंतर संपीड़ित फ़ाइल पर सीमित प्रभाव होना चाहिए। - hmijail


विधि जो बाइट जोड़ / हटाना के लिए काम करती है

diff <(od -An -tx1 -w1 -v file1) \
     <(od -An -tx1 -w1 -v file2)

बाइट 64 के एकल हटाने के साथ एक परीक्षण केस उत्पन्न करें:

for i in `seq 128`; do printf "%02x" "$i"; done | xxd -r -p > file1
for i in `seq 128`; do if [ "$i" -ne 64 ]; then printf "%02x" $i; fi; done | xxd -r -p > file2

आउटपुट:

64d63
<  40

यदि आप चरित्र के ASCII संस्करण को भी देखना चाहते हैं:

bdiff() (
  f() (
    od -An -tx1c -w1 -v "$1" | paste -d '' - -
  )
  diff <(f "$1") <(f "$2")
)

bdiff file1 file2

आउटपुट:

64d63
<   40   @

उबंटू 16.04 पर परीक्षण किया गया।

मैं पसंद करता हूं od ऊपर xxd इसलिये:

  • यह पॉज़िक्स है, xxd नहीं है (विम के साथ आता है)
  • है -An बिना पता कॉलम को हटाने के लिए awk

कमांड स्पष्टीकरण:

  • -An पता कॉलम हटा देता है। यह महत्वपूर्ण है अन्यथा बाइट अतिरिक्त / हटाने के बाद सभी लाइनें अलग-अलग होंगी।
  • -w1 प्रति पंक्ति एक बाइट रखता है, ताकि diff इसका उपभोग कर सके। प्रति पंक्ति एक बाइट होना महत्वपूर्ण है, या फिर हटाने के बाद प्रत्येक पंक्ति चरण से बाहर हो जाएगी और अलग हो जाएगी। दुर्भाग्यवश, यह पॉज़िक्स नहीं है, लेकिन जीएनयू में मौजूद है।
  • -tx1 वह प्रतिनिधित्व है जो आप चाहते हैं, किसी भी संभावित मूल्य में बदलें, जब तक आप प्रति पंक्ति 1 बाइट रखें।
  • -v तारांकन पुनरावृत्ति संक्षेप को रोकता है * जो diff के साथ हस्तक्षेप कर सकता है
  • paste -d '' - - हर दो लाइनों में शामिल हो जाता है। हमें इसकी आवश्यकता है क्योंकि हेक्स और एएससीआईआई अलग-अलग आसन्न लाइनों में जाते हैं। से लिया गया: https://stackoverflow.com/questions/8987257/concatenating-every-other-line-with-the-next
  • हम कंस्ट्रैसिस का उपयोग करते हैं () परिभाषित करना bdiff के बजाय {} आंतरिक समारोह के दायरे को सीमित करने के लिए f, यह भी देखें: https://stackoverflow.com/questions/8426077/how-to-define-a-function-inside-another-function-in-bash

यह भी देखें:


25
2018-04-04 20:31





संक्षिप्त जवाब

vimdiff <(xxd -c1 -p first.bin) <(xxd -c1 -p second.bin)

विशेष रूप से बाइनरी फ़ाइलों की तुलना करने के लिए हेक्सडंप और टेक्स्ट diff का उपयोग करते समय xxd, बाइट्स के जोड़ और निष्कासन संबोधित करने में बदलाव बन जाते हैं जो इसे देखना मुश्किल हो सकता है। यह विधि एक्सएक्सडी को आउटपुट पतों को नहीं बताती है, और प्रति पंक्ति केवल एक बाइट आउटपुट करने के लिए बताती है, जो बदले में दिखाती है कि कौन से बाइट बदल दिए गए, जोड़े गए या हटा दिए गए। आप बाइट्स के दिलचस्प अनुक्रमों को और अधिक "सामान्य" हेक्सडंप (आउटपुट) में खोज कर बाद में पते पा सकते हैं xxd first.bin)।


13
2018-04-22 12:10



(बेशक, कोई भी उपयोग कर सकते हैं diff के बजाय vimdiff।) - VasyaNovikov


मैं डिस्प्ले के लिए बाइनरी फाइलों को डंपिंग टेक्स्ट प्रारूप और केडीएफ 3 के लिए हेक्सडम्प की सिफारिश करता हूं।

hexdump myfile1.bin > myfile1.hex
hexdump myfile2.bin > myfile2.hex
kdiff3 myfile1.hex myfile2.hex

11
2018-06-12 07:46



यहां तक ​​कि बाश में भी kdiff3 <(hexdump myfile1.bin) <(hexdump myfile2.bin) फ़ाइलों को बनाने की जरूरत नहीं है myfile1.hex तथा myfile2.hex। - Hastur


hexdiff एक ऐसा प्रोग्राम है जो आप जो भी खोज रहे हैं उसे करने के लिए डिज़ाइन किया गया है।

उपयोग:

hexdiff file1 file2

यह किसी भी अंतर को हाइलाइट किए जाने के साथ-साथ दो फ़ाइलों में से एक की हेक्स (और 7-बिट ASCII) प्रदर्शित करता है। की ओर देखें man hexdiff आदेशों के लिए फ़ाइल में चारों ओर स्थानांतरित करने के लिए, और एक सरल q छोड़ देंगे


4
2017-10-07 04:11



लेकिन यह तुलना करने की बात आती है जब यह एक बहुत बुरा काम करता है। यदि आप किसी फ़ाइल में कुछ बाइट्स डालते हैं, तो यह बाद में सभी बाइट को परिवर्तन के रूप में चिह्नित करेगा - Murmel
और हेक्सडिफ उबंटू 16.4 पर एपीटी-गेट के माध्यम से उपलब्ध नहीं है - rubo77
@Murmel जबकि मैं सहमत हूं, यह नहीं है कि यहां क्या पूछा जा रहा है? - Evan Carroll
@EvanCarroll सच है, और इसलिए मैंने एक टिप्पणी छोड़ दी (केवल) और डाउनवोट नहीं किया - Murmel
मैंने मिक को भी वोट नहीं दिया, लेकिन मैं आपसे सहमत हूं और यहां जवाब दिया superuser.com/a/1373977/11116 क्योंकि ऐसा लगता है कि यह बुरा सवाल सुधार या बंद हो जाएगा। - Evan Carroll


यह सख्ती से सवाल का जवाब नहीं दे सकता है, लेकिन मैं इसे अलग-अलग द्विआधारी के लिए उपयोग करता हूं:

gvim -d <(xxd -c 1 ~/file1.bin | awk '{print $2, $3}') <(xxd -c 1 ~/file2.bin | awk '{print $2, $3}')

यह दोनों फाइलों को हेक्स के रूप में प्रिंट करता है और ASCII मूल्य, प्रति पंक्ति एक बाइट, और फिर उन्हें दृश्यमान रूप से प्रस्तुत करने के लिए विम की diff सुविधा का उपयोग करता है।


3
2017-09-07 15:47