How can I convert bytes object to decimal or binary representation in python?
Starting from Python 3.2, you can use int.from_bytes
.
Second argument, byteorder
, specifies endianness of your bytestring. It can be either 'big'
or 'little'
. You can also use sys.byteorder
to get your host machine's native byteorder.
import sys
int.from_bytes(b'\x11', byteorder=sys.byteorder) # => 17
bin(int.from_bytes(b'\x11', byteorder=sys.byteorder)) # => '0b10001'
Python byte array to bit array
That will work:
def access_bit(data, num):
base = int(num // 8)
shift = int(num % 8)
return (data[base] >> shift) & 0x1
If you'd like to create a binary array you can use it like this:
[access_bit(data,i) for i in range(len(data)*8)]
python bytes to bit string
What about some combination of formatting (below with f-string but can be done otherwise), and slicing:
def bytes2binstr(b, n=None):
s = ' '.join(f'{x:08b}' for x in b)
return s if n is None else s[:n + n // 8 + (0 if n % 8 else -1)]
If I understood correctly (I am not sure what the B
at the end is supposed to mean), it passes your tests and a couple more:
func = bytes2binstr
args = (
(b'\x80\x00', None),
(b'\x80\x00', 14),
(b'\x0f\x00', 14),
(b'\xff\xff\xff\xff\xf0\x00', 16),
(b'\xff\xff\xff\xff\xf0\x00', 22),
(b'\x0f\xff\xff\xff\xf0\x00', 45),
(b'\xff\xff\xff\xff\xf0\x00', 45),
)
for arg in args:
print(arg)
print(repr(func(*arg)))
# (b'\x80\x00', None)
# '10000000 00000000'
# (b'\x80\x00', 14)
# '10000000 000000'
# (b'\x0f\x00', 14)
# '00001111 000000'
# (b'\xff\xff\xff\xff\xf0\x00', 16)
# '11111111 11111111'
# (b'\xff\xff\xff\xff\xf0\x00', 22)
# '11111111 11111111 111111'
# (b'\x0f\xff\xff\xff\xf0\x00', 45)
# '00001111 11111111 11111111 11111111 11110000 00000'
# (b'\xff\xff\xff\xff\xf0\x00', 45)
# '11111111 11111111 11111111 11111111 11110000 00000'
Explanation- we start from a
bytes
object - iterating through it gives us a single byte as a number
- each byte is 8 bit, so decoding that will already give us the correct separation
- each byte is formatted using the
b
binary specifier, with some additional formatting: 0
zero fill, 8
minimum length - we join (concatenate) the result of the formatting using
' '
as "separator" - finally the result is returned as is if a maximum number of bits
n
was not specified (set to None
), otherwise the result is cropped to n
+ the number of spaces that were added in-between the 8-character groups.
bytes
objectb
binary specifier, with some additional formatting: 0
zero fill, 8
minimum length' '
as "separator"n
was not specified (set to None
), otherwise the result is cropped to n
+ the number of spaces that were added in-between the 8-character groups.In the solution above 8
is somewhat hard-coded.
If you want it to be a parameter, you may want to look into (possibly a variation of) @kederrac first answer using int.from_bytes()
.
This could look something like:
def bytes2binstr_frombytes(b, n=None, k=8):
s = '{x:0{m}b}'.format(m=len(b) * 8, x=int.from_bytes(b, byteorder='big'))[:n]
return ' '.join([s[i:i + k] for i in range(0, len(s), k)])
which gives the same output as above.
Speedwise, the int.from_bytes()
-based solution is also faster:
for i in range(2, 7):
n = 10 ** i
print(n)
b = b''.join([random.randint(0, 2 ** 8 - 1).to_bytes(1, 'big') for _ in range(n)])
for func in funcs:
print(func.__name__, funcs[0](b, n * 7) == func(b, n * 7))
%timeit func(b, n * 7)
print()
# 100
# bytes2binstr True
# 10000 loops, best of 3: 33.9 µs per loop
# bytes2binstr_frombytes True
# 100000 loops, best of 3: 15.1 µs per loop
# 1000
# bytes2binstr True
# 1000 loops, best of 3: 332 µs per loop
# bytes2binstr_frombytes True
# 10000 loops, best of 3: 134 µs per loop
# 10000
# bytes2binstr True
# 100 loops, best of 3: 3.29 ms per loop
# bytes2binstr_frombytes True
# 1000 loops, best of 3: 1.33 ms per loop
# 100000
# bytes2binstr True
# 10 loops, best of 3: 37.7 ms per loop
# bytes2binstr_frombytes True
# 100 loops, best of 3: 16.7 ms per loop
# 1000000
# bytes2binstr True
# 1 loop, best of 3: 400 ms per loop
# bytes2binstr_frombytes True
# 10 loops, best of 3: 190 ms per loop
Python - Convert bytearray to binary data, then select bits
@Axe319
Your post only partly answers my question.
Thanks to you, I got:
import sys
a = bytearray(b'\x10\x10\x10')
b = bin(int.from_bytes(a, byteorder=sys.byteorder))
print(b)
0b100000001000000010000
Then, to select four bits, I found from Python: How do I extract specific bits from a byte?:
def access_4bits(data, num):
# access 4 bits from num-th position in data
return bin(int(data, 2) >> num & 0b1111)
c = access_4bits(b, 4)
print(c)
0b1
How can I convert from bytes to binary numbers in Python?
You could try int.from_bytes(...)
, documented here e.g.:
>>> byte_obj = b'\x45\x10\x00\x4c\xcc\xde\x40\x00\x40\x06\x6c\x80\xc0\xa8\xd9\x17\x8d\x54\xda\x28'
>>> int.from_bytes(byte_obj, byteorder='big')
394277201243797802270421732363840487422965373480
Where byteorder
is used to specify whether the input is big- or little-endian (i.e. most or least significant byte first).
(Looks a bit bigger than 32 bits though!)
python how to convert bytes to binary
To get a (somewhat) accurate representation of the string as it is stored in memory, you need to convert each character into binary.
Assuming basic ascii (1 byte per character) encoding:
s = "python"
binlst = [bin(ord(c))[2:].rjust(8,'0') for c in s] # remove '0b' from string, fill 8 bits
binstr = ''.join(binlst)
print(s)
print(binlst)
print(binstr)
Output
python
['01110000', '01111001', '01110100', '01101000', '01101111', '01101110']
011100000111100101110100011010000110111101101110
For unicode (utf-8), the length of each character can be 1-4 bytes so it's difficult to determine the exact binary representation. As @Yellen mentioned, it may be easier to just convert the file bytes to binary.
Related Topics
How to Print a Percentage Value in Python
How to Plot Normal Distribution
How to Draw Axis in the Middle of the Figure
Creating Lowpass Filter in Scipy - Understanding Methods and Units
Django Model "Doesn't Declare an Explicit App_Label"
Find Element's Index in Pandas Series
Sqlite3, Operationalerror: Unable to Open Database File
Get List of All Routes Defined in the Flask App
Python Slice How-To, I Know the Python Slice But How to Use Built-In Slice Object for It
Pandas Unique Values Multiple Columns
Why Do I Get "Pickle - Eoferror: Ran Out of Input" Reading an Empty File
For Loops and Iterating Through Lists
How to Treat Python Argparse.Namespace() as a Dictionary
Error: Pg_Config Executable Not Found When Installing Psycopg2 on Alpine in Docker