sql >> Base de Datos >  >> NoSQL >> Redis

¿Cómo podría convertir un byte en una cadena hexadecimal completa?

Al iterar sobre un bytes valor, obtienes números enteros; estos se convierten trivialmente a notación hexadecimal:

def convert(value: bytes):
    return ''.join([f'\\x{b:02x}' for b in value])

Tenga en cuenta que esto produce una cadena con barras invertidas literales, x caracteres y dígitos hexadecimales . Ya no es un bytes valor.

Demostración:

>>> print(convert(b'\x01\x02\x41'))
\x01\x02\x41

Solo para asegurarse, no necesita preocuparse por los bytes valor . El repr() representación de un bytes El objeto siempre usará caracteres ASCII cuando el valor del byte sea el de un punto de código ASCII imprimible. Eso no significa que el valor haya cambiado. b'\x01\x02\x41' es igual a b'\x01\x02A' . El protocolo Redis no sabe nada sobre \x<HH> secuencias de escape, así que no intentes enviar la cadena anterior por el cable.

Las secuencias de escape que produce son secuencias de cadenas de shell bash , y al igual que las cadenas de Python, no tiene que usar escapes . Como en Python, para Bash las cadenas "\x01\x02A" y "\x01\x02\x41" tienen valores iguales. Solo tienen sentido cuando pasa la clave y las cadenas de valor en la línea de comando, no en un archivo de texto que canaliza a redis-cli .

Además, tenga en cuenta que redis-cli --pipe el comando toma entrada de protocolo Redis sin procesar , no la sintaxis de comandos de Redis, consulte Inserción masiva de Redis documentación. Este protocolo no usa \xhh secuencias, ya que no utiliza la notación shell.

En su lugar, use la siguiente función para generar SET sin procesar comandos:

def raw_protocol(cmd: str, *args: bytes):
    return b'\r\n'.join([
        f'*{len(args) + 1}\r\n${len(cmd)}\r\n{cmd}'.encode(),
        *(bv for a in args for bv in (b'$%d' % len(a), a)),
        b''
    ])

Para un SET comando, use raw_protocol('SET', keybytes, valuebytes) y escriba los datos binarios que esto produce en un archivo abierto en modo binario.