سؤال كيف أقارن الملفات الثنائية في لينكس؟


ولست بحاجة لمقارنة اثنين من الملفات الثنائية والحصول على الإخراج في النموذج

<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


الأصل


كنت في الأساس تبحث عن "ثنائي فرق". يمكنني أن أتخيل بعض commande قبيحة واحدة مع الخطوط od... - quack quixote
@ quackote quixote: ما هو الشيء القبيح بالنسبة للواحد؟ ؛) - Bobby
يعمل xdelta.org بشكل جيد. ربما يستحق الأمر إلقاء نظرة عليه. - thatjuan
لأنه لا يمكنك الإجابة هذا السؤال (لأنك لست مستخدمًا) ، فأنا أصوت على الإغلاق. الاختلافات الثنائية كما هو مطلوب بشكل صريح هنا ليست مفيدة على الإطلاق ، وأنا أميل إلى الاعتقاد بأنك تريد شيئًا مفيدًا ، إذا قمت بإدراج بايت واحد في بداية الملف يجب أن يتم وضع علامة جميع البايتات بأنها مختلفة؟ دون معرفة ذلك ، هذا ببساطة غامضة للغاية. - 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 - على سبيل المثال ، 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. أعتقد أن Ubuntu كانت تستخدم 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



في Bash: diff <(xxd b1) <(xxd b2) لكن تنسيق إخراج هذا (أو ملكك) ليس قريبًا مما طلبه OP. - Dennis Williamson
مع vimdiff ، فإنه سيتم تلوين البايتات في الخطوط حيث يختلف "الملفان" - akira
عذرًا ، لماذا لم أفكر في ذلك؟ وأنا متأكد من أنني استخدمت هذه التقنية في الماضي أيضًا. - njd
هذا عمل عظيم بالنسبة لي (مع opendiff على OS X بدلا من vimdiff) - العرض الافتراضي xxd يوفر الحفاظ على محرك فرق في المسار مقارنة بايت بايت. مع عادي (خام) عرافة ببساطة تناسب العمود مع fold، diff سيحاول طي / تجميع الأشياء العشوائية في الملفات التي كنت أقارنها. - natevw
هذا الأمر لا يعمل بشكل جيد لإزالة إضافة البايتات ، حيث أن كل خط يتبع سيكون محاذاة بشكل غير صحيح وينظر إليه على أنه معدّل بواسطة diff. الحل هو وضع 1 بايت لكل سطر وإزالة عمود العنوان كما هو مقترح من قبل جون لورنس آسبدن و أنا. - Ciro Santilli 新疆改造中心 六四事件 法轮功


محاولة diff في المزيج التالي من استبدال عملية zsh / bash و colordiff في CLI:

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

أين:

  • -y يظهر لك الاختلافات جنبًا إلى جنب (اختياري)
  • xxd هي أداة CLI لإنشاء مخرجات ملف hexdump للملف الثنائي
  • 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
إذا لم يكن لديك colordiff ، فإن هذا سيفعل الشيء نفسه بدون الألوان: 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 -  سوف تفعل وظيفة جيدة بما فيه الكفاية - ribamar


هناك أداة تسمى DHEX التي قد تقوم بهذه المهمة ، وهناك أداة أخرى تسمى VBinDiff.

للحصول على نهج سطر الأوامر بدقة ، حاول JDIFF.


48
2018-03-29 15:41



DHEX رائع هو مقارنة الثنائيات هو ما تريد القيام به. قم بتزويده بملفين ويأخذك مباشرة إلى عرض مقارن ، مع إبراز الاختلافات ، مع القدرة على الانتقال بسهولة إلى الاختلاف التالي. كما أنها قادرة على العمل مع المحطات الطرفية الكبيرة ، وهو أمر مفيد للغاية على الشاشات العريضة. - Marcin
أنا أفضل VBinDiff. DHEX يستخدم وحدة المعالجة المركزية حتى عند التباطؤ ، وأعتقد أنه إعادة رسم طوال الوقت أو شيء من هذا. لا يعمل VBinDiff مع أجهزة طرفية واسعة بالرغم من ذلك. ولكن العناوين تصبح غريبة مع محطات واسعة على أي حال ، لأن لديك أكثر من 16 بايت لكل صف. - Janus Troelsen
vbindiff يتيح لنا بالفعل تحرير الملف ، تشك! - Aquarius Power
ستكون الملفات المضغوطةDanielBeauyat مختلفة تمامًا بعد مواجهة البايت الأول المختلف. من غير المحتمل أن يكون الإخراج مفيدًا. - Mark Ransom
@ 1111161171159459134 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   @

تم اختباره على Ubuntu 16.04.

أنا أفضل od على xxd لان:

  • هذا هو POSIX، xxd ليس (يأتي مع فيم)
  • لديه -An لإزالة عمود العنوان بدون awk.

شرح الأمر:

  • -An يزيل عمود العنوان. هذا أمر مهم وإلا فإن جميع الخطوط ستختلف بعد إضافة / إزالة البايت.
  • -w1 يضع بايتًا واحدًا في كل سطر ، بحيث يمكن أن يستهلكه الاختلاف. من الأهمية بمكان أن يكون لديك بايت واحد في كل سطر ، وإلا فإن كل سطر بعد حذفه سيصبح خارج المرحلة ويختلف. للأسف ، هذا ليس POSIX ، ولكنه موجود في GNU.
  • -tx1 هو التمثيل الذي تريده ، وتغييره إلى أي قيمة ممكنة ، طالما أنك تحتفظ بمقدار 1 بايت في كل سطر.
  • -v يمنع اختصار التكرار النجمية * والتي قد تتداخل مع فرق
  • paste -d '' - - ينضم كل خطين. نحن بحاجة إليها لأن السداسي و ASCII يدخلان في خطوط متجاورة منفصلة. مأخوذ من: 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)

عند استخدام hexdumps و diff diff للمقارنة بين الملفات الثنائية ، خاصة xxdتصبح الإضافات وعمليات إزالة وحدات البايت تحولات في المعالجة قد تجعل من الصعب رؤيتها. تخبر هذه الطريقة xxd بعدم إخراج العناوين ، وإخراج بايت واحد فقط في كل سطر ، مما يُظهر بدوره البايتات التي تم تغييرها أو إضافتها أو إزالتها. يمكنك العثور على العناوين في وقت لاحق من خلال البحث عن تسلسلات مثيرة للاهتمام من بايت في hexdump أكثر "طبيعية" (إخراج xxd first.bin).


13
2018-04-22 12:10



(بالطبع ، يمكن للمرء أن يستخدم diff بدلا من vimdiff.) - VasyaNovikov


أنصح hexdump لإغراق الملفات الثنائية إلى تنسيق نصي و kdiff3 للعرض diff.

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
و hexdiff غير متوفر عبر apt-get على Ubuntu 16.4 - rubo77
Murmel بينما أوافق ، أليس هذا ما يجري طرحه هنا؟ - Evan Carroll
EvanCarroll صحيح ، وبالتالي تركت تعليقًا (فقط) ولم أتراجع - Murmel
أنا أيضا لم أقم بالتصويت ميك ، ولكن أنا أتفق معك وأجبت هنا superuser.com/a/1373977/11116 لأنه يبدو من المحتمل أن يتم إصلاح هذه القضية أو إغلاقها. - Evan Carroll