Reputation: 19871
I have a string as follows:
b'\x00\x00\x00\x00\x07\x80\x00\x03'
How can I convert this to an array of bytes? ... and back to a string from the bytes?
Upvotes: 38
Views: 117887
Reputation: 50076
There is generally no need to do this. The string-like ASCII representation of bytes
is just that, a representation. A bytes
object, as e.g. created by a b
-string literal, already is an (immutable, fixed size) array of bytes.
While bytes literals and representations are based on ASCII text,
bytes
objects actually behave like immutable sequences of integers, with each value in the sequence restricted such that0 <= x < 256
.
For example, one can index a bytes
object to get a specific byte datum or iterate a bytes
object to work with every individual byte.
>>> blob = b"\x00\x00\x00\x00\x07\x80\x00\x03"
>>> blob[0], blob[-1] # index to get specific byte
(0, 3)
>>> for datum in blob: # iterate over each byte
... if datum:
... print(datum)
7
128
3
If mutability is required, bytearray
is the appropriate type. This also supports all mutable sequence methods, such as assignment by index or the .append
method.
One can efficiently convert between mutable and immutable bytes by simply passing them to the appropriate class. For example, bytearray(b"\x00\x00\x07\x80\x00\x03")
creates a mutable array of bytes out of a bytes
literal.
Note that both bytes
and bytearray
are optimised for holding byte elements. The objects have a backing memory buffer of an actual byte array as one would use in a C-like language.
+ <bytes> + +-------------------
| *buffer | -> | \x00 \x03 \x00 ...
| ... | +-------------------
+---------+
In contrast, general purpose containers of bytes, say a list[int]
or even list[bytes]
, use the full Python representation for elements. Instead of storing an array of byte data, they store a sequence of references to Python objects that in turn refer to an individual byte datum each.
+ <list> ---+ +-------------------
| *elements | -> | *0 *1 *2 ...
| ... | +-------------------
+-----------+ / |
/ |
v v
+ <int> --+ + <int> --+
| *digits | | *digits | -> +---+
| ... | | ... | | 1 |
+---------+ +---------+ +---+
Thus, converting bytes
to list
or similar should be avoided unless absolutely necessary.
Upvotes: 3
Reputation: 1613
From string to array of bytes:
a = bytearray.fromhex('00 00 00 00 07 80 00 03')
or
a = bytearray(b'\x00\x00\x00\x00\x07\x80\x00\x03')
and back to string:
key = ''.join(chr(x) for x in a)
Upvotes: 16
Reputation: 713
in python 3:
>>> a=b'\x00\x00\x00\x00\x07\x80\x00\x03'
>>> b = list(a)
>>> b
[0, 0, 0, 0, 7, 128, 0, 3]
>>> c = bytes(b)
>>> c
b'\x00\x00\x00\x00\x07\x80\x00\x03'
>>>
Upvotes: 47