Domanda

ok quindi il mio problema è che ho la stringa '\ 222 \ 222 \ 223 \ 225' che è memorizzata come latin-1 nel db. Quello che ottengo da Django (stampandolo) è la seguente stringa, '& # 226; & # 226; & # 226; & # 226; & # 162;' che presumo sia la sua conversione UTF. Ora ho bisogno di passare la stringa in una funzione che esegue questa operazione:

strdecryptedPassword + chr(ord(c) - 3 - intCounter - 30)

Ottengo questo errore:

  

chr () arg non nel range (256)

Se provo a codificare la stringa come latin-1 prima ottengo questo errore:

  

Il codec 'latin-1' non può codificare i caratteri nella posizione 0-3: ordinale no   nell'intervallo (256)

Ho letto un sacco di cose su come funziona la codifica dei caratteri e c'è qualcosa che mi manca perché non capisco!

È stato utile?

Soluzione

Il tuo primo errore 'chr () arg non nel range (256)' probabilmente significa che hai sottovalutato il valore, perché chr non può prendere numeri negativi. Non so che cosa dovrebbe fare l'algoritmo di crittografia quando inputcounter + 33 è più della rappresentazione reale del personaggio, dovrai controllare cosa fare in quel caso.

Informazioni sul secondo errore. è necessario decodificare () e non codificare () un oggetto stringa normale per ottenere una rappresentazione corretta dei dati. encode () accetta un oggetto unicode (quelli che iniziano con u ') e genera una stringa regolare da inviare o scrivere su un file. decode () accetta un oggetto stringa e genera un oggetto unicode con i corrispondenti punti di codice. Questo viene fatto con la chiamata unicode () quando generato da un oggetto stringa, è possibile anche chiamare a.decode ('latin-1') invece.

>>> a = '\222\222\223\225'
>>> u = unicode(a,'latin-1')
>>> u
u'\x92\x92\x93\x95'
>>> print u.encode('utf-8')
ÂÂÂÂ
>>> print u.encode('utf-16')
ÿþ
>>> print u.encode('latin-1')

>>> for c in u:
...   print chr(ord(c) - 3 - 0 -30)
...
q
q
r
t
>>> for c in u:
...   print chr(ord(c) - 3 -200 -30)
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError: chr() arg not in range(256)

Altri suggerimenti

Come osserva Vinko, Latin-1 o ISO 8859-1 non ha caratteri stampabili per la stringa ottale che citi. Secondo le mie note per 8859-1, i controlli "C1 (0x80 - 0x9F) provengono da ISO / IEC 6429: 1992. Non definisce nomi per 80, 81 o 99 ". I nomi dei punti di codice sono elencati da Vinko:

\222 = 0x92 => PRIVATE USE TWO
\223 = 0x93 => SET TRANSMIT STATE
\225 = 0x95 => MESSAGE WAITING

La codifica UTF-8 corretta è (Unicode, binary, hex):

U+0092 = %11000010 %10010010 = 0xC2 0x92
U+0093 = %11000010 %10010011 = 0xC2 0x93
U+0095 = %11000010 %10010101 = 0xC2 0x95

La LETTERA PICCOLA LATINA A CON CIRCUMFLEX è ISO 8859-1 codice 0xE2 e quindi Unicode U + 00E2; in UTF-8, ovvero% 11000011% 10100010 o 0xC3 0xA2.

Il CENT CENTRO è ISO 8859-1 codice 0xA2 e quindi Unicode U + 00A2; in UTF-8, ovvero% 11000011% 10000010 o 0xC3 0x82.

Quindi, qualunque cosa tu stia vedendo, non sembra che tu stia vedendo una codifica UTF-8 di ISO 8859-1. A parte tutto, vedrai solo 5 byte dove dovresti vedere 8.

Aggiunto : La parte precedente della risposta affronta l'affermazione "codifica UTF-8", ma ignora il resto della domanda, che dice:

Now I need to pass the string into a function that does this operation:

    strdecryptedPassword + chr(ord(c) - 3 - intCounter - 30)

I get this error: chr() arg not in range(256).  If I try to encode the
string as Latin-1 first I get this error: 'latin-1' codec can't encode
characters in position 0-3: ordinal not in range(256).

In realtà non ci mostri come è definito intCounter, ma se aumenta delicatamente per carattere, prima o poi ' ord (c) - 3 - intCounter - 30 ' sarà negativo (e, a proposito, perché non combinare le costanti e usare ' ord (c) - intCounter - 33 '?), a quel punto, chr () è probabile lamentarsi. Dovresti aggiungere 256 se il valore è negativo o utilizzare un'operazione di modulo per assicurarti di avere un valore positivo compreso tra 0 e 255 per passare a chr () . Dal momento che non possiamo vedere come viene incrementato intCounter, non possiamo dire se passa da 0 a 255 o se aumenta monotonicamente. In quest'ultimo caso, hai bisogno di un'espressione come:

chr(mod(ord(c) - mod(intCounter, 255) + 479, 255))

dove 256 - 33 = 223, ovviamente, e 479 = 256 + 223. Ciò garantisce che il valore passato a chr () sia positivo e compreso nell'intervallo 0..255 per qualsiasi input carattere c e qualsiasi valore di intCounter (e, poiché la funzione mod () non ottiene mai un argomento negativo, funziona anche indipendentemente da come mod () si comporta quando i suoi argomenti sono negativo).

Beh, è ??perché è stato crittografato con uno schema terribile che cambia l'ordine () del personaggio con una richiesta, quindi la stringa che esce dal database è stata crittografata e questo lo decodifica. Ciò che hai fornito sopra non sembra funzionare. Nel database è latin-1, django lo converte in unicode, ma non riesco a passarlo alla funzione come unicode, ma quando provo a codificarlo in latin-1 vedo quell'errore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top