Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

Como eu poderia converter um bytes em uma string hexadecimal inteira?


Ao iterar sobre um bytes valor, você obtém números inteiros; estes são trivialmente convertidos em notação hexadecimal:
def convert(value: bytes):
    return ''.join([f'\\x{b:02x}' for b in value])

Observe que isso produz uma string com barras invertidas literais, x caracteres e caracteres de dígitos hexadecimais . Não é mais um bytes valor.

Demonstração:
>>> print(convert(b'\x01\x02\x41'))
\x01\x02\x41

Só para ter certeza, você não precisa se preocupar com os bytes valor . O repr() representação de um bytes O objeto sempre usará caracteres ASCII quando o valor do byte for o de um ponto de código ASCII imprimível. Isso não significa que o valor foi alterado. b'\x01\x02\x41' é igual a b'\x01\x02A' . O protocolo Redis não sabe nada sobre \x<HH> seqüências de escape, então não tente enviar a string acima pelo fio.

As sequências de escape que você produz são sequências de strings do shell bash , e assim como as strings do Python, você não precisa usar escapes . Como em Python, para bash as strings "\x01\x02A" e "\x01\x02\x41" têm valores iguais. Eles só fazem sentido quando você está passando as strings de chave e valor na linha de comando, não em um arquivo de texto que você canaliza para redis-cli .

Além disso, observe que o redis-cli --pipe comando recebe entrada bruta do protocolo Redis , não a sintaxe de comando do Redis, consulte a Inserção em massa do Redis documentação. Este protocolo não use \xhh sequências, pois não usa notação de shell.

Em vez disso, use a seguinte função para gerar SET bruto 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 um SET comando, use raw_protocol('SET', keybytes, valuebytes) e escreva os dados binários que isso produz em um arquivo aberto no modo binário.