باستخدام Python كيف يمكنني قراءة البتات في بايت؟

StackOverflow https://stackoverflow.com/questions/2576712

  •  24-09-2019
  •  | 
  •  

سؤال

لدي ملف حيث يحتوي البايت الأول على معلومات مشفرة. في Matlab يمكنني قراءة البايت شيئًا فشيئًا var = fread(file, 8, 'ubit1'), ثم استرجع كل بت var(1), var(2), ، إلخ.

هل هناك أي قارئ بتات مكافئ في بيثون؟

هل كانت مفيدة؟

المحلول

اقرأ البتات من ملف ، بتات منخفضة أولاً.

def bits(f):
    bytes = (ord(b) for b in f.read())
    for b in bytes:
        for i in xrange(8):
            yield (b >> i) & 1

for b in bits(open('binary-file.bin', 'r')):
    print b

نصائح أخرى

أصغر وحدة ستتمكن من العمل معها هي بايت. للعمل على مستوى البت الذي تحتاج إلى استخدامه مشغلات bitwise.

x = 3
#Check if the 1st bit is set:
x&1 != 0
#Returns True

#Check if the 2nd bit is set:
x&2 != 0
#Returns True

#Check if the 3rd bit is set:
x&4 != 0
#Returns False

لن تتمكن من قراءة كل بت واحد تلو الآخر - عليك قراءته بايت بايت. يمكنك بسهولة استخراج البتات ، على الرغم من:

f = open("myfile", 'rb')
# read one byte
byte = f.read(1)
# convert the byte to an integer representation
byte = ord(byte)
# now convert to string of 1s and 0s
byte = bin(byte)[2:].rjust(8, '0')
# now byte contains a string with 0s and 1s
for bit in byte:
    print bit

مع numpy من السهل مثل هذا:

Bytes = numpy.fromfile(filename, dtype = "uint8")
Bits = numpy.unpackbits(Bytes)

مزيد من المعلومات هنا:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.fromfile.html

لقراءة بايت من ملف: bytestring = open(filename, 'rb').read(1). ملاحظة: يتم فتح الملف في الثنائية الوضع.

للحصول على أجزاء ، قم بتحويل البايت إلى عدد صحيح: byte = bytestring[0] (بيثون 3) أو byte = ord(bytestring[0]) (Python 2) واستخراج البت المطلوب: (byte >> i) & 1:

>>> for i in range(8): (b'a'[0] >> i) & 1
... 
1
0
0
0
0
1
1
0
>>> bin(b'a'[0])
'0b1100001'

الانضمام إلى بعض الإجابات السابقة التي سأستخدمها:

[int(i) for i in "{0:08b}".format(byte)]

لكل بايت قراءة من الملف. نتائج مثال بايت 0x88 هي:

>>> [int(i) for i in "{0:08b}".format(0x88)]
[1, 0, 0, 0, 1, 0, 0, 0]

يمكنك تعيينه لمتغير والعمل حسب طلبك الأولي. "{0.08}" هو ضمان طول البايت الكامل

هناك طريقتان محتملين لإرجاع البايت الأول من البايت. يمكن أن يشير "البت الأول" إلى بت عالية الترتيب أو يمكن أن يشير إلى بتات الترتيب السفلية.

فيما يلي وظيفة تأخذ سلسلة وفهرس كمعلمات وإرجاع قيمة البت في هذا الموقع. كما هو مكتوب ، فإنه يعامل بت منخفض من الدرجة المنخفضة باعتباره الجزء الأول. إذا كنت تريد بتات عالية أولاً ، فما عليك سوى إلغاء تحديد الخط المشار إليه.

def bit_from_string(string, index):
       i, j = divmod(index, 8)

       # Uncomment this if you want the high-order bit first
       # j = 8 - j

       if ord(string[i]) & (1 << j):
              return 1
       else:
              return 0

يبدأ الفهرسة عند 0. إذا كنت تريد أن تبدأ الفهرسة من 1 ، فيمكنك ضبط الفهرس في الوظيفة قبل الاتصال divmod.

مثال الاستخدام:

>>> for i in range(8):
>>>       print i, bit_from_string('\x04', i)
0 0
1 0
2 1
3 0
4 0
5 0
6 0
7 0

الآن ، لكيفية عمله:

تتكون السلسلة من بايت 8 بت ، لذلك نستخدم أولاً DivMod () لكسر الفهرس إلى أجزاء:

  • i: فهرس البايت الصحيح داخل السلسلة
  • j: فهرس البت الصحيح داخل ذلك البايت

نحن نستخدم ال ord() وظيفة لتحويل الحرف في string[i] في نوع عدد صحيح. ثم، (1 << j) يحسب قيمة بت j-th عن طريق التحول اليساري 1 بواسطة j. أخيرًا ، نستخدم bitwise-واختبار ما إذا كان هذا البت قد تم تعيينه. إذا كان الأمر كذلك ، فأعود 1 ، وإلا إرجاع 0.

هذا سريع جدا أعتقد:

import itertools
data = range(10)
format = "{:0>8b}".format
newdata = (False if n == '0' else True for n in itertools.chain.from_iterable(map(format, data)))
print(newdata) # prints tons of True and False

لنفترض أن لديك ملفًا يسمى bloom_filter.bin الذي يحتوي على مجموعة من البتات وتريد قراءة الملف بأكمله واستخدام تلك البتات في صفيف.

قم أولاً بإنشاء الصفيف حيث سيتم تخزين البتات بعد القراءة ،

from bitarray import bitarray
a=bitarray(size)           #same as the number of bits in the file

افتح الملف ، باستخدام مفتوح أو مع ، أي شيء على ما يرام ... أنا متمسك بفتح هنا ،

f=open('bloom_filter.bin','rb')

الآن قم بتحميل جميع البتات في الصفيف "A" في طلقة واحدة باستخدام ،

f.readinto(a)

'a' هو الآن bitarray يحتوي على جميع البتات

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top