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?

Walter A
  • 19,067
  • 2
  • 23
  • 43
needoriginalname
  • 703
  • 3
  • 9
  • 27
  • how many bytes does it have? is it 3 or was that just an example? – Dleep Aug 07 '15 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). – thebjorn Aug 07 '15 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. – needoriginalname Aug 07 '15 at 18:58

3 Answers3

5

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

>>> x = 7485254
>>> bin(x)
'0b11100100011011101000110'
>>> bin(x << 1)
'0b111001000110111010001100'
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
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')
Pierz
  • 7,064
  • 52
  • 59
-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
thebjorn
  • 26,297
  • 11
  • 96
  • 138
  • 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](http://stackoverflow.com/a/28524760/4279). See also, [Convert Binary to ASCII and vice versa (Python)](http://stackoverflow.com/q/7396849/4279) – jfs Aug 08 '15 at 22:53
  • @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). – thebjorn Aug 09 '15 at 13:44
  • If you want to show byte at a time operation; you could [use `bytearray()` that is Python 2/3, Pypy compatible](http://stackoverflow.com/a/15916760/4279) – jfs Aug 09 '15 at 13:56
  • 1
    Is anyone actually using Python 3/Pypy? – thebjorn Aug 09 '15 at 15:33
  • I just tested `bytearray` performance on Python 2.7.10 (using the example at the bottom of http://www.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). – thebjorn Aug 09 '15 at 18:17