[Python-es] Classe para tratamiento de bits

Xin xinxic en gmail.com
Mar Ago 28 10:08:35 CEST 2007


Hola,

Hace poco tube la necesidad de trabajar con streams de bits de 
diferentes tamaños y poder extraer diferentes valors de estos. Como no 
he encontrado ningun tipo de mòdulo o classe me la he hecho yo mismo.

La idea és poder trabajar con ello como si de un número de tratara. Así 
que su funcionamiento és el siguiente:

> # Intanciacion
> >>> b = Bits('1111000010010110',base=2)
> >>> b
> 61590L
> >>> hex(b)
> '0xF096L'
> >>> b = Bits(61590)
> >>> b = Bits('1111000010010110',start=4,end=12,base=2)
> >>> b
> 9L
> >>> hex(b)
> '0x9L'


> # Subbits
> >>> b = Bits(61590L)
> >>> hex(b)
> '0xF096L'
> >>> bb = b[4:12]
> >>> bb
> 9L
> >>> hex(bb)
> '0x9L'
> >>> b[3]
> 0L
> >>> b[2]
> 1L
> >>> b[1]
> 1L
> >>> b[0]
> 0L

Quizàs faltaria alguna funcion más, però para mi ya tenia suficiente.
Y también seria mejor que no guardara todos los sub-valores.
Espero que os sirva. Este és el codigo.

> class Bits(long):
>     """
>     Classe per treballar amb un long i els seus bits.
>     """
>
>     def __new__(cls,value,start=None,end=None,base=10):
>         """
>         Inicialitzem com si fos un número qualsevol.
>         Després treurem els bits que ens interessin.
>         El end no hi és inclòs.
>         """
>
>         if (start is not None and start < 0) or \
>            (end is not None and end < 0):
>             raise ValueError("start and end must be positive")
>
>         l = long(str(value),base)
>
>         if start is not None:   l >>= start
>         else:                   start = 0
>
>         if end is not None:
>             if start >= end:
>                 raise ValueError("invalid start and end of Bits(): %i, 
> %i" % (start,end))
>             mask = ( 0x01 << (end-start) ) - 1
>             l &= mask
>
>         return long.__new__(cls,l)
>
>     def __init__(self,value,start=None,end=None,base=10):
>         self.words = {}
>
>     def __getitem__(self,key):
>         """
>         Permet retornar un conjunt de bits com un enter
>         """
>
>         # Muntem un slice vàlid i n'obtenim els l´ímits
>         if type(key) == types.IntType:
>             key = slice(key,key+1,1)
>         start,stop,step = key.start,key.stop,key.step
>
>         # Retornem la paraula guardant-ne una còpia
>         if (start,stop) not in self.words:
>             try:
>                 self.words[(start,stop)] = Bits(self,start,stop)
>             except ValueError:
>                 raise KeyError('Bit index out of range')
>         return self.words[(start,stop)]


Xin


Más información sobre la lista de distribución Python-es