Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python bytes concatenation

Tags:

I want to concatenate the first byte of a bytes string to the end of the string:

a = b'\x14\xf6' a += a[0] 

I get an error:

Traceback (most recent call last):   File "<stdin>", line 1, in <module> TypeError: can't concat bytes to int 

When I type bytes(a[0]) I get:

b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 

And bytes({a[0]}) gives the correct b'\x14'.

Why do I need {} ?

like image 775
Alexandre AMORTILA Avatar asked Jan 24 '15 21:01

Alexandre AMORTILA


2 Answers

If you want to change your byte sequence, you should use a bytearray. It is mutable and has the .append method:

>>> a = bytearray(b'\x14\xf6') >>> a.append(a[0]) >>> a bytearray(b'\x14\xf6\x14') 

What happens in your approach: when you do

a += a[0] 

you are trying to add an integer to a bytes object. That doesn't make sense, since you are trying to add different types.

If you do

bytes(a[0]) 

you get a bytes object of length 20, as the documentation describes:

If [the argument] is an integer, the array will have that size and will be initialized with null bytes.

If you use curly braces, you are creating a set, and a different option in the constructor is chosen:

If it is an iterable, it must be an iterable of integers in the range 0 <= x < 256, which are used as the initial contents of the array.

like image 77
Jasper Avatar answered Oct 22 '22 05:10

Jasper


Bytes don't work quite like strings. When you index with a single value (rather than a slice), you get an integer, rather than a length-one bytes instance. In your case, a[0] is 20 (hex 0x14).

A similar issue happens with the bytes constructor. If you pass a single integer in as the argument (rather than an iterable), you get a bytes instance that consists of that many null bytes ("\x00"). This explains why bytes(a[0]) gives you twenty null bytes. The version with the curly brackets works because it creates a set (which is iterable).

To do what you want, I suggest slicing a[0:1] rather than indexing with a single value. This will give you a bytes instance that you can concatenate onto your existing value.

a += a[0:1] 
like image 22
Blckknght Avatar answered Oct 22 '22 04:10

Blckknght