معالجة البيانات الثنائية في بيثون
-
28-09-2019 - |
سؤال
أنا أفتح ملف ثنائي مثل ذلك:
file = open("test/test.x", 'rb')
والقراءة في خطوط إلى قائمة. كل سطر يشبه إلى حد ما:
'\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n'
أواجه صعوبة في معالجة هذه البيانات. إذا حاولت طباعة كل سطر ، يتجمد بيثون ، وينبعث من أصوات الصفير (أعتقد أن هناك رمز صوت ثنائي في مكان ما). كيف يمكنني استخدام هذه البيانات بأمان؟ كيف يمكنني تحويل كل رقم سداسي عشري إلى عشري؟
المحلول
لطباعته ، يمكنك أن تفعل شيئًا كهذا:
print repr(data)
لكل شيء باسم Hex:
print data.encode('hex')
للقيمة العشرية لكل بايت:
print ' '.join([str(ord(a)) for a in data])
لتفريغ الأعداد الصحيحة الثنائية ، وما إلى ذلك من البيانات كما لو أنها جاءت في الأصل من بنية على غرار C ، انظر إلى بنية وحدة.
نصائح أخرى
\xhh
هل الشخصية ذات القيمة السداسية HH. شخصيات أخرى مثل .
و `~ 'شخصيات طبيعية.
يمنحك التكرار على سلسلة الأحرف فيه ، واحدة تلو الأخرى.
ord(c)
سيعود عدد صحيح يمثل الشخصية. على سبيل المثال ، ord('A') == 65
.
سيؤدي ذلك إلى طباعة الأرقام العشرية لكل حرف:
s = '\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n'
print ' '.join(str(ord(c)) for c in s)
مثل Theatrus المذكورة ، قد يساعدك Ord و Hex. إذا كنت ترغب في محاولة تفسير نوع من البيانات الثنائية المنظمة في الملف ، بنية قد تكون الوحدة مفيدة.
نادراً ما تنقسم البيانات الثنائية إلى "خطوط" مفصولة بـ ' n'. إذا كان الأمر كذلك ، فسيكون لها آلية هروب ضمنية أو صريحة للتمييز بين " n" كمحصول خط و " n" كجزء من البيانات. قراءة مثل هذا الملف كخطوط عمياء دون معرفة آلية الهروب أمر لا معنى له.
للإجابة على اهتماماتك المحددة:
" x07" هي شخصية ASCII BEL ، والتي كانت في الأصل لرنين الجرس على جهاز teletype.
يمكنك الحصول على قيمة عدد صحيح من البايت "B" من خلال العمل ord(b)
.
ومع ذلك ، لمعالجة البيانات الثنائية بشكل صحيح ، تحتاج إلى معرفة ماهية التصميم. يمكن أن يكون لديك أعداد صحيحة موقعة وغير موقعة (من الأحجام 1 ، 2 ، 4 ، 8 بايت) ، وأرقام نقاط عائمة ، وأعداد عشرية من الأطوال المتغيرة ، وأسلاك الطول الثابت ، وأسلاك الطول المتغيرة ، إلخ. بأسلوب كبير أو أزياء صغيرة. بمجرد أن تعرف كل ما سبق (أو لديك تخمينات جيدة جدًا) ، وحدة بنية بيثون يجب أن تكون قادرة على استخدامها لجميع أو معظم معالجتك ؛ ال وحدة Ctypes قد تكون مفيدة أيضا.
هل تنسيق البيانات له اسم؟ إذا كان الأمر كذلك ، أخبرنا ؛ قد نكون قادرين على توجيهك إلى رمز أو مستندات.
تسأل "كيف يمكنني استخدام هذه البيانات بأمان؟" ما الذي يطرح السؤال: ماذا تريد استخدامه؟ ما هي التلاعب التي تريد القيام بها؟
أنت تحاول طباعة البيانات التي تم تحويلها إلى أحرف ASCII ، والتي لن تعمل.
يمكنك استخدام أي بايت من البيانات بأمان. إذا كنت ترغب في طباعته على أنه سداسي عشري ، فابحث عن الوظائف ord
و hex
/
هل تستخدم read()
أو readline()
؟ يجب أن تستخدم read(n)
لقراءة ن بايت. readline()
سوف تقرأ حتى يصل إلى سطر جديد ، والذي قد لا يكون للملف الثنائي.
في كلتا الحالتين ، على الرغم من ذلك ، يتم إرجاع سلسلة من البايتات ، والتي قد تكون قابلة للطباعة أو غير قابلة للطباعة ، وربما ليست مفيدة للغاية.
ما تريد ord()
, ، الذي يحول سلسلة بايت واحدة إلى قيمة عدد صحيح المقابلة. read()
من الملف الأول بايت في وقت واحد ومكالمة ord()
على النتيجة ، أو تكرار من خلال السلسلة بأكملها.
إذا كنت على استعداد لاستخدام Numpy و Bitstream, ، يمكنك ان تفعل
>>> from numpy import *
>>> from bitstream import BitStream
>>> raw = '\xbe\x00\xc8d\xf8d\x08\xe4.\x07~\x03\x9e\x07\xbe\x03\xde\x07\xfe\n'
>>> stream = BitStream(raw)
>>> stream.read(raw, uint8, len(stream) // 8)
array([190, 0, 200, 100, 248, 100, 8, 228, 46, 7, 126, 3, 158,
7, 190, 3, 222, 7, 254, 10], dtype=uint8)