2011-06-08 12 views
6

Esta falla, no es sorprendente:¿Es posible realizar operaciones bit a bit en una cadena en Python?

>>> 'abc' << 8 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for <<: 'str' and 'int' 
>>> 

Con ascii abc igual a 011000010110001001100011 o 6382179, hay una manera de cambiar que una cierta cantidad arbitraria de modo 'abc' << 8 habría 01100001011000100110001100000000?

¿Qué ocurre con otras operaciones bit a bit? 'abc' & 63 = 100011, etc.?

+0

Atención a explicar por qué quiere esto? Quizás podríamos encontrar una alternativa. – Nix

+0

Sí ... realmente no veo un caso de uso ... sería mejor almacenar un número y luego transformarlo en una cadena cuando se necesitara salir, pero aún así ... – cwallenpoole

+0

curosidad realmente; algo había surgido donde podría haber sido útil. Nunca terminé necesitándolo, solo me hizo comenzar a pensar. – tMC

Respuesta

7

Lo que probablemente desee es el módulo de cadena de bits (consulte http://code.google.com/p/python-bitstring/). Parece que admite operaciones bit a bit así como muchas otras manipulaciones de matrices de bits. Pero debe tener cuidado de introducir bytes en él (por ejemplo, b'abc' o bytes('abc')), no caracteres: los caracteres pueden contener Unicode y ocupar más de un byte.

7

No tiene sentido realizar operaciones en modo bit en las cadenas. Es posible que desee utilizar el módulo struct para convertir sus cadenas en números:

>>> import struct 
>>> x = 'abc' 
>>> x = '\x00' * (4-len(x)) + x 
>>> number = struct.unpack('!i', x)[0] 
>>> number 
6382179 

A continuación, puede hacer todas sus operaciones en number. Cuando (si) quiere una cadena de regreso, puede hacer struct.pack('!i', number).

+2

¿No tiene sentido? No seas tan general; ¿Qué sucede si quiero cambiar el número de una cadena por 4 para prepararla para la codificación RS en un código QR? –

+0

No sé sobre las operaciones bit a bit en cadenas, pero la estructura funcionó muy bien para mí. Aquí está el caso de uso. El formato de archivo SGF existe para grabar ciertos juegos. En el caso de Go, se reproduce en una placa de 19x19, las coordenadas en el archivo SGF se dan en caracteres alfabéticos en minúsculas. Necesito convertirlos a coordenadas x-y numéricas estándar, y esta respuesta funciona perfectamente para eso. ¡Gracias! – cb4

1

Escribí un par de funciones para convertir ascii en int y volver usando solo builtins. Puede que haya mezclado el MSB/LSB, así que estoy usando [::-1] para invertir las cadenas de entrada. Solución fácil si no te gusta el orden.

disfrutar de:

>>> intstr = lambda z : ''.join([str(unichr((z & (255*(256**i)))/(256**i))) for i in range(0,((len(bin(z)) - 2)/8) + (1 if ((len(bin(z)) - 2)/8) else 0))]) 
>>> strint = lambda z : reduce(lambda x,y: x | y, [ord(str(z)[i])*((2**8)**i) for i in range(len(str(z)))]) 
>>> strint('abc'[::-1]) 
6382179 
>>> bin(strint('abc'[::-1]) & 63) 
'0b100011' 
>>> bin(strint('abc'[::-1]) << 8) 
'0b1100001011000100110001100000000' 
Cuestiones relacionadas