82

Say that I have a 4 character string, and I want to convert this string into a byte array where each character in the string is translated into its hex equivalent. e.g.

str = "ABCD"

I'm trying to get my output to be

array('B', [41, 42, 43, 44])

Is there a straightforward way to accomplish this?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
AndroidDev
  • 20,466
  • 42
  • 148
  • 239
  • 3
    What you want is not possible, at least not in this exact form. A bytearray of type `B` contains 1-byte integers, and they are always represented in decimal. – Tim Pietzcker Jul 24 '12 at 04:50

9 Answers9

66

encode function can help you here, encode returns an encoded version of the string

In [44]: str = "ABCD"

In [45]: [elem.encode("hex") for elem in str]
Out[45]: ['41', '42', '43', '44']

or you can use array module

In [49]: import array

In [50]: print array.array('B', "ABCD")
array('B', [65, 66, 67, 68])
avasal
  • 14,350
  • 4
  • 31
  • 47
  • however as you can see,, array module gives a ascii value of string elements, which doesn't match with your expected output – avasal Jul 24 '12 at 04:51
  • 21
    This is the accepted answer and does not work in Python3. Could you please add the python3 version as pointed in other answers? – Fabio Picchi Oct 24 '18 at 14:14
66

Just use a bytearray() which is a list of bytes.

Python2:

s = "ABCD"
b = bytearray()
b.extend(s)

Python3:

s = "ABCD"
b = bytearray()
b.extend(map(ord, s))

By the way, don't use str as a variable name since that is builtin.

Pithikos
  • 18,827
  • 15
  • 113
  • 136
  • This is broken in 3.4: `TypeError: an integer is required` – Kevan Ahlquist Apr 10 '15 at 02:43
  • 1
    @KevanAhlquist my bad. Fixed it now. – Pithikos Apr 13 '15 at 15:29
  • 12
    For Python 3 this looks cleaner to me: `s = "ABCD"`, `b = bytearray()`, `b.extend(s.encode())` – Diego Herranz Jun 15 '16 at 16:53
  • 7
    Regarding [encode()](https://docs.python.org/3.4/library/stdtypes.html#str.encode), it returns a bytes object which naturally extends a bytearray. – Diego Herranz Jun 15 '16 at 17:00
  • 2
    `map(ord, s)` will return values > 255 unless your strings are strictly ASCII. Please update your answer to include something like `s.encode('utf-8')`. (Note that UTF-8 is a strict superset of ASCII, so it does not alter ASCII strings in any way.) – 9000 Feb 14 '18 at 20:54
  • 2
    @9000 it is incorrect to use `.encode()` as well as `.encode('utf-8')`. Use `map(ord, ...)` if you don't want you bytes to be transformed. https://repl.it/repls/MistySubtleVisitors just press `run` and see the result. – user70960 Mar 18 '20 at 13:26
  • in my use case (socket send), only `b.extend(map(ord, s))` works, none of the following works: `s.encode(), s.encode(‘ascii’), bytearray(s.encode())` – ios learner Mar 02 '21 at 23:47
24

An alternative to get a byte array is to encode the string in ascii: b=s.encode('ascii').

josliber
  • 43,891
  • 12
  • 98
  • 133
Jon Perryman
  • 381
  • 3
  • 4
13

Depending on your needs, this can be one step or two steps

  1. use encode() to convert string to bytes, immutable
  2. use bytearray() to convert bytes to bytearray, mutable
s="ABCD"
encoded=s.encode('utf-8')
array=bytearray(encoded)

The following validation is done in Python 3.7

>>> s="ABCD"
>>> encoded=s.encode('utf-8')
>>> encoded
b'ABCD'
>>> array=bytearray(encoded)
>>> array
bytearray(b'ABCD')
Lleims
  • 1,275
  • 12
  • 39
oldpride
  • 761
  • 7
  • 15
10

This works for me (Python 2)

s = "ABCD"
b = bytearray(s)

# if you print whole b, it still displays it as if its original string
print b

# but print first item from the array to see byte value
print b[0]

Reference: http://www.dotnetperls.com/bytes-python

mgear
  • 1,333
  • 2
  • 22
  • 39
9

This work in both Python 2 and 3:

>>> bytearray(b'ABCD')
bytearray(b'ABCD')

Note string started with b.

To get individual chars:

>>> print("DEC HEX ASC")
... for b in bytearray(b'ABCD'):
...     print(b, hex(b), chr(b))
DEC HEX ASC
65 0x41 A
66 0x42 B
67 0x43 C
68 0x44 D

Hope this helps

juliocesar
  • 5,706
  • 8
  • 44
  • 63
1
s = "ABCD"
from array import array
a = array("B", s)

If you want hex:

print map(hex, a)
Anthony
  • 12,177
  • 9
  • 69
  • 105
HYRY
  • 94,853
  • 25
  • 187
  • 187
  • 1
    Does not work in repl.it. Returns: "TypeError: cannot use a str to initialize an array with typecode 'B' " – MikeB2019x Mar 12 '20 at 14:22
1

Since none of the answers is producing exactly array('B', [41, 42, 43, 44]) and the answer by avasal fails in Python 3, I post here my alternative:

import array
s = 'ABCD'
a = array.array('B', [ord(c) for c in s])
print(a)

which prints

array('B', [65, 66, 67, 68])

Note that 65-68 is the correct ASCII for "ABCD".

user171780
  • 2,243
  • 1
  • 20
  • 43
-1

for python 3 it worked for what @HYRY posted. I needed it for a returned data in a dbus.array. This is the only way it worked

s = "ABCD"

from array import array

a = array("B", s)
Zoe
  • 27,060
  • 21
  • 118
  • 148