2012-01-11 51 views
12

Tôi đang làm việc với Python3.2. Tôi cần phải lấy một dòng hex như là một đầu vào và phân tích nó ở mức bit. Vì vậy, tôi đã sử dụngChuyển đổi byte thành bit trong python

bytes.fromhex(input_str)

để chuyển đổi chuỗi thành byte thực. Bây giờ làm thế nào để chuyển đổi các byte này thành bit?

+1

Byte là bit, chỉ 8 tại một thời điểm;) - Câu trả lời phụ thuộc vào những gì bạn muốn làm, hãy cụ thể hơn Đồng thời thao tác bit chủ yếu được thực hiện ở cấp byte ... –

+0

Tôi muốn đại diện cho các byte trong hình thức một chuỗi bit để tôi có thể làm một cái gì đó như: field1 = bit_string [0: 1] field2 = bit_string [1:16] và cứ thế – user904832

Trả lời

10

Còn thứ gì đó như thế này?

>>> bin(int('ff', base=16)) 
'0b11111111' 

Điều này sẽ chuyển đổi chuỗi thập lục phân bạn có thành số nguyên và số nguyên thành chuỗi trong đó mỗi byte được đặt thành 0/1 tùy thuộc vào giá trị bit của số nguyên.

Như đã chỉ ra bởi một nhận xét, nếu bạn cần để thoát khỏi tiền tố 0b, bạn có thể làm theo cách này:

>>> bin(int('ff', base=16)).lstrip('0b') 
11111111 

hoặc theo cách này:

>>> bin(int('ff', base=16))[2:] 
11111111 
+0

lstrip ('- 0b') # xóa số 0 và dấu trừ đầu – ahoffer

+0

@ahoffer Cảm ơn bạn đã bình luận. Tôi đã cập nhật câu trả lời của mình để OP biết cách xóa tiền tố '0b'. – jcollado

+4

Lưu ý rằng 'lstrip ('0b')' cũng sẽ loại bỏ, giả sử '00bb' vì đối số thành' lstrip' là một tập hợp * các ký tự cần xóa. Nó sẽ hoạt động tốt trong trường hợp này, nhưng tôi thích giải pháp '[2:]' vì nó rõ ràng hơn. –

14

Operations là nhiều nhanh hơn khi bạn làm việc ở cấp nguyên. Đặc biệt, việc chuyển đổi thành chuỗi như được đề xuất ở đây thực sự chậm.

Nếu bạn chỉ muốn bit 7 và 8, hãy sử dụng ví dụ:

val = (byte >> 6) & 3 

(này là:. Chuyển byte 6 bit sang bên phải - Sau đó thả chúng giữ chỉ có hai bit cuối cùng 3 là một số với hai bit đầu tiên thiết lập ...)

Những thể dễ dàng được dịch sang các hoạt động CPU đơn giản siêu nhanh.

23

Một cách khác để làm điều này là bằng cách sử dụng các mô-đun bitstring:

>>> from bitstring import BitArray 
>>> input_str = '0xff' 
>>> c = BitArray(hex=input_str) 
>>> c.bin 
'0b11111111' 

Và nếu bạn cần phải dải hàng đầu 0b:

>>> c.bin[2:] 
'11111111' 

Module bitstring không phải là một yêu cầu, như jcollado hiển thị câu trả lời, nhưng nó có rất nhiều phương pháp thực hiện để chuyển đầu vào thành bit và thao tác chúng. Bạn có thể tìm thấy tiện dụng này (hoặc không), ví dụ:

>>> c.uint 
255 
>>> c.invert() 
>>> c.bin[2:] 
'00000000' 

, vv

+1

+1. Và đối với phiên bản mới nhất của bitstring (3.0), bạn không cần phải tách '0b' hàng đầu. –

4

Để nhị phân:

bin(byte)[2:].zfill(8) 
+0

Bạn không thể chuyển đổi byte bằng bin. – user3467349

3

Tôi nghĩ đơn giản nhất sẽ được sử dụng numpy đây.Ví dụ, bạn có thể đọc một tập tin như byte và sau đó mở rộng nó thành từng mảnh một cách dễ dàng như thế này:

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

Sử dụng ord khi đọc byte đọc:

byte_binary = bin(ord(f.read(1))) # Add [2:] to remove the "0b" prefix 

Hoặc

Sử dụng str.format():

'{:08b}'.format(ord(f.read(1))) 
0

Đây là cách để làm điều đó bằng format()

print "bin_signedDate : ", ''.join(format(x, '08b') for x in bytevector) 

Điều quan trọng các 08b là. Điều đó có nghĩa là sẽ có tối đa 8 số 0 đầu được nối thêm để hoàn thành một byte. Nếu bạn không chỉ định điều này thì định dạng sẽ chỉ có độ dài bit biến cho mỗi byte được chuyển đổi.

0

Những câu trả lời khác ở đây cung cấp các bit trong big-endian trật tự ('\x01' trở thành '00000001')

Trong trường hợp bạn đang quan tâm để ít về cuối nhỏ bit, đó là hữu ích trong nhiều trường hợp, như tuyên bố chung của bignums vv - đây là một đoạn trích cho rằng:

def bits_little_endian_from_bytes(s): 
    return ''.join(bin(ord(x))[2:].rjust(8,'0')[::-1] for x in s) 

Và đối với một hướng khác:

def bytes_from_bits_little_endian(s): 
    return ''.join(chr(int(s[i:i+8][::-1], 2)) for i in range(0, len(s), 8)) 
Các vấn đề liên quan