Redis
 sql >> Database >  >> NoSQL >> Redis

Come posso convertire un byte in un'intera stringa esadecimale?

Durante l'iterazione su un bytes valore, ottieni numeri interi; questi sono banalmente convertiti in notazione esadecimale:

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

Nota che questo produce una stringa con barre inverse letterali, x caratteri e caratteri numerici esadecimali . Non è più un bytes valore.

Demo:

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

Giusto per essere sicuro, non devi preoccuparti dei bytes valore . Il repr() rappresentazione di un bytes l'oggetto utilizzerà sempre caratteri ASCII quando il valore del byte è quello di un codepoint ASCII stampabile. Ciò non significa che il valore sia cambiato. b'\x01\x02\x41' è uguale a b'\x01\x02A' . Il protocollo Redis non sa nulla di \x<HH> sequenze di escape, quindi non provare a inviare la stringa sopra via cavo.

Le sequenze di escape che produci sono sequenze di stringhe della shell bash e proprio come le stringhe Python, non è necessario utilizzare gli escape . Come in Python, per Bash le stringhe "\x01\x02A" e "\x01\x02\x41" hanno valori uguali. Hanno senso solo quando si passano le stringhe di chiavi e valori sulla riga di comando, non in un file di testo che si reindirizza a redis-cli .

Inoltre, tieni presente che il redis-cli --pipe il comando accetta input grezzo del protocollo Redis , non la sintassi del comando Redis, vedere Inserimento di massa Redis documentazione. Questo protocollo non usa \xhh sequenze, poiché non usa la notazione della shell.

Invece, usa la seguente funzione per generare SET non elaborato comandi:

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''
    ])

Per un SET comando, usa raw_protocol('SET', keybytes, valuebytes) e scrivi i dati binari che questo produce in un file aperto in modalità binaria.