Working with bytes.

Anton Vredegoor anton at vredegoor.doge.nl
Sat Apr 3 16:57:25 EST 2004


"Adam T. Gautier" <adam_gautier at yahoo.com> wrote:

>I came up with a solution using the binascii module's hexlify method.

That is the most obvious method, I think. However, the code below
stores 7 bits per byte and still remains ascii-compliant (the
binascii.hexlify method stores 4 bits per byte).

Anton

from itertools import islice

def _bits(i):
    return [('01'[i>>j & 1]) for j in range(8)][::-1] 

_table = dict([(chr(i),_bits(i)) for i in range(256)])

def _bitstream(bytes):
    for byte in bytes:
        for bit in _table[byte]:
            yield bit

def _dropfirst(gen):
    while 1:
        gen.next()
        for x in islice(gen,7):
            yield x

def sevens(bytes):
    """ stream normal bytes to bytes where bit 8 is always 1"""
    gen = _bitstream(bytes)
    while 1:
        R = list(islice(gen,7))
        if not R:  break
        s = '1'+ "".join(R) + '0' * (7-len(R))
        yield chr(int(s,2))

def eights(bytes,n):
    """ the reverse of the sevens function :-) """
    gen = _bitstream(bytes)
    df = _dropfirst(gen)
    for i in xrange(n):
        s =  ''.join(islice(df,8))
        yield chr(int(s,2))
        
def test():
    from random import randint
    size = 40
    R = [chr(randint(0,255)) for i in xrange(size)]
    bytes = ''.join(R)
    sv =  ''.join(sevens(bytes))
    check = ''.join(eights(sv,size))
    assert  check == bytes
    print sv

if __name__ == '__main__': 
    test()

sample output:

 Ÿæ‰®ÑëÍ¡¾÷ÁóÆú½Þ·ú˂זðÚ¿‹ˆ²ªÅíž›¾Ÿ£•Í£¬ô²ŸÕØ

 




More information about the Python-list mailing list