4

I want to convert an encoding to another encoding in Python for a school project. However, the encoding I am translating from will add a padding to its encoding on the first bit.

How do I shift an binary number sequence to the left by one, so that it goes from:

00000001 11001100 01010101 and so on

to

00000011 10011000 10101010 and so on

so the end result's lowest bit will be the former's highest bit number?

3
  • how many bytes does it have? is it 3 or was that just an example? Commented Aug 7, 2015 at 18:53
  • At some point you'll need to test the leftmost bit before doing a left shift. You can optimize how often you'll need to do that by eg. packing multiple bytes into a larger int (check the struct module). Commented Aug 7, 2015 at 18:54
  • just 3 is an example, but its a continuously growing number. As its actually data transmitted from somewhere and its needs to be converted out to be printed in a different format. Commented Aug 7, 2015 at 18:58

3 Answers 3

5

You can use the << operator to left shift, and conversely >> will right shift

>>> x = 7485254
>>> bin(x)
'0b11100100011011101000110'
>>> bin(x << 1)
'0b111001000110111010001100'
Sign up to request clarification or add additional context in comments.

Comments

1

You could use the bitstring library which allows for bitwise operations on arbitrarily long bitstrings e.g. to import and shift your binary number:

>>> import bitstring
>>> bitstring.BitArray(bin='0b11100100011011101000110') << 1
BitArray('0b11001000110111010001100')

Comments

-3

You can convert the string to one big integer and then do the left-shift (and then convert the big integer back into a string):

large_int = bytes2int(mystring)
large_int <<= 1
mystring = int2bytes(large_int)

using e.g. this simplistic implementation:

def bytes2int(str):
    res = ord(str[0])
    for ch in str[1:]:
        res <<= 8
        res |= ord(ch)
    return res

def int2bytes(n):
    res = []
    while n:
        ch = n & 0b11111111
        res.append(chr(ch))
        n >>= 8
    return ''.join(reversed(res))

bytes = 'abcdefghijklmnopqrstuv'
assert int2bytes(bytes2int(bytes)) == bytes

5 Comments

It is inefficient to process one byte at a time. You could use int.from_bytes(), int.to_bytes() methods on Python 3 and binascii.unhexlify on Python 2. See also, Convert Binary to ASCII and vice versa (Python)
@J.F.Sebastian you're absolutely correct, hence the note about 'simplistic' implementation (the OP is doing binary encoding work, so I figured a bit-fiddling example could be interesting).
If you want to show byte at a time operation; you could use bytearray() that is Python 2/3, Pypy compatible
Is anyone actually using Python 3/Pypy? <wink>
I just tested bytearray performance on Python 2.7.10 (using the example at the bottom of dotnetperls.com/bytes), and it seems like it is almost 10% slower than a plain list. FWIW, I would expect PyPy to be able to optimize the functions in the answer without any problems (Cython makes it about twice as fast with very few changes).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.