Pregunta

ok, entonces mi problema es que tengo la cadena '\ 222 \ 222 \ 223 \ 225' que está almacenada como latin-1 en la base de datos. Lo que obtengo de django (imprimiéndolo) es la siguiente cadena, 'ââââ ¢', que supongo que es la conversión UTF de la misma. Ahora necesito pasar la cadena a una función que realiza esta operación:

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

Me sale este error:

  

chr () arg no está en el rango (256)

Si primero intento codificar la cadena como latin-1, aparece este error:

  El códec

'latin-1' no puede codificar caracteres en la posición 0-3: ordinal no   en rango (256)

¡He leído un montón sobre cómo funciona la codificación de caracteres, y hay algo que me falta porque simplemente no lo entiendo!

¿Fue útil?

Solución

Su primer error 'chr () arg no está en el rango (256)' probablemente significa que ha desbordado el valor, porque chr no puede tomar números negativos. No sé qué se supone que debe hacer el algoritmo de cifrado cuando inputcounter + 33 es más que la representación de caracteres real, tendrá que verificar qué hacer en ese caso.

Sobre el segundo error. debe decodificar () y no codificar () un objeto de cadena regular para obtener una representación adecuada de sus datos. encode () toma un objeto unicode (aquellos que comienzan con u ') y genera una cadena regular para salir o escribir en un archivo. decode () toma un objeto de cadena y genera un objeto unicode con los puntos de código correspondientes. Esto se hace con la llamada unicode () cuando se genera a partir de un objeto de cadena, también puede llamar a a.decode ('latin-1') en su lugar.

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

Otros consejos

Como señala Vinko, Latin-1 o ISO 8859-1 no tiene caracteres imprimibles para la cadena octal que cita. De acuerdo con mis notas para 8859-1, los controles C1 (0x80 - 0x9F) son de ISO / IEC 6429: 1992. No define nombres para 80, 81 o 99 ''. Los nombres de los puntos de código son los que Vinko los enumera:

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

La codificación correcta UTF-8 de esos es (Unicode, binario, hexadecimal):

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

La LETRA A PEQUEÑA LATINA CON CIRCUMFLEX es ISO 8859-1 código 0xE2 y, por lo tanto, Unicode U + 00E2; en UTF-8, eso es% 11000011% 10100010 o 0xC3 0xA2.

El SIGNO CENT es el código ISO 8859-1 0xA2 y, por lo tanto, Unicode U + 00A2; en UTF-8, eso es% 11000011% 10000010 o 0xC3 0x82.

Entonces, cualquier cosa que esté viendo, no parece estar viendo una codificación UTF-8 de ISO 8859-1. Todo lo demás aparte, estás viendo pero 5 bytes donde tendrías que ver 8.

Agregado : La parte anterior de la respuesta aborda el reclamo de 'codificación UTF-8', pero ignora el resto de la pregunta, que 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).

En realidad no nos muestra cómo se define intCounter, pero si se incrementa suavemente por carácter, tarde o temprano ' ord (c) - 3 - intCounter - 30 ' será negativo (y, por cierto, ¿por qué no combinar las constantes y usar ' ord (c) - intCounter - 33 '?), en ese punto, es probable que chr () quejarse. Debería agregar 256 si el valor es negativo, o usar una operación de módulo para asegurarse de que tiene un valor positivo entre 0 y 255 para pasar a chr () . Dado que no podemos ver cómo se incrementa intCounter, no podemos saber si cambia de 0 a 255 o si aumenta monotónicamente. Si es lo último, entonces necesita una expresión como:

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

donde 256 - 33 = 223, por supuesto, y 479 = 256 + 223. Esto garantiza que el valor pasado a chr () es positivo y en el rango 0..255 para cualquier entrada el carácter c y cualquier valor de intCounter (y, dado que la función mod () nunca obtiene un argumento negativo, también funciona independientemente de cómo se comporta mod () cuando sus argumentos son negativo).

Bueno, es porque ha sido encriptado con algún esquema terrible que solo cambia el ord () del personaje por alguna solicitud, por lo que la cadena que sale de la base de datos ha sido encriptada y esto la desencripta. Lo que proporcionó anteriormente no parece funcionar. En la base de datos es latin-1, django lo convierte a unicode, pero no puedo pasarlo a la función como unicode, pero cuando intento codificarlo a latin-1 veo ese error.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top