problemas de conversão UTF-8 Latin-1, python django

votos
3

ok assim que meu problema é que eu tenho a string '\ 222 \ 222 \ 223 \ 225', que é armazenado como latin-1 no db. O que eu recebo de Django (por imprimi-lo) é a seguinte cadeia, 'AAAA ¢' que eu suponho que é a conversão UTF dele. Agora eu preciso passar a string em uma função que faz esta operação:

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

Eu recebo este erro:

CHR () não arg na gama (256)

Se eu tentar codificar a string como latin-1 primeiro eu recebo este erro:

codec 'latino-1' não é possível codificar os caracteres na posição 0-3: não ordinal na gama (256)

Eu li um monte sobre como codificação de caracteres funciona, e há algo que eu estou ausente porque eu simplesmente não entendo!

Publicado 08/11/2008 em 05:24
fonte usuário
Em outras línguas...                            


3 respostas

votos
4

Seu primeiro erro 'chr () não arg in range (256)' provavelmente significa que você underflowed o valor, porque chr não pode ter números negativos. Eu não sei o que o algoritmo de criptografia é suposto fazer quando o inputcounter + 33 é mais do que a representação de caráter real, você terá que verificar o que fazer nesse caso.

Sobre o segundo erro. você deve decodificar () e não codificar () um objeto string regular para obter uma representação adequada dos seus dados. encode () leva um objeto unicode (aqueles começando com u ') e gera uma seqüência regular para ser de saída ou gravados em um arquivo. descodificar () leva um objeto de cadeia e gerar um objeto Unicode com os pontos de código correspondentes. Isto é feito com a chamada unicode () quando gerado a partir de um objeto string, você também pode chamar a.decode ( 'latin-1') em vez.

>>> 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)
Respondeu 08/11/2008 em 06:29
fonte usuário

votos
2

Como Vinko observa, Latin-1 ou ISO 8859-1 não tem caracteres imprimíveis para a string octal você cita. De acordo com as minhas anotações para 8859-1, "Controles C1 (0x80 - 0x9F) são da ISO / IEC 6429: 1992 Ela não define nomes para 80, 81 ou 99.". Os nomes de pontos de código são os Vinko lista deles:

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

A correcta UTF-8 daqueles é (Unicode, binário, hex):

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

O a minúsculo com acento circunflexo é ISO 8859-1 código 0xE2 e, portanto, Unicode U + 00E2; em UTF-8, que é%% 11000011 10100010 ou 0xC3 0xA2.

O SINAL CENT é ISO 8859-1 0xA2 código e, portanto, Unicode U + 00A2; em UTF-8, que é%% 11000011 10000010 ou 0xC3 0x82.

Então, tudo aquilo que você está vendo, você não parece estar vendo uma codificação UTF-8 da ISO 8859-1. Tudo o mais distante, você está vendo, mas 5 bytes, onde você teria que ver 8.

Adicionado : A parte anterior da resposta aborda a reivindicação 'UTF-8', mas ignora o resto da questão, que diz:

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

Você realmente não nos mostrar como intCounter está definido, mas se incrementa suavemente por personagem, mais cedo ou mais tarde ' ord(c) - 3 - intCounter - 30' vai ser negativo (e, a propósito, por que não combinar as constantes e uso ' ord(c) - intCounter - 33'?), Pelo que ponto, chr()é provável que reclamar. Você precisa adicionar 256 se o valor for negativo, ou usar uma operação de módulo para garantir que tem um valor positivo entre 0 e 255 para passar para chr(). Como não podemos ver como intCounter é incrementado, não podemos dizer se os ciclos de 0 a 255 ou se aumenta monotonamente. Neste último caso, então você precisa de uma expressão como:

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

onde 256-33 = 223, é claro, e 479 = 256 + 223. Isto garante que o valor transmitido ao chr()é positivo e na gama 0..255 para qualquer carácter de entrada C e qualquer valor de intCounter (e, porque a mod()função nunca fica um argumento negativo, ele também funciona independentemente de como mod()se comporta quando seus argumentos são negativos).

Respondeu 08/11/2008 em 07:08
fonte usuário

votos
0

Bem, é porque sua sido criptografada com algum esquema terrível que apenas muda a ord () do caráter por algum pedido, assim que a corda que sai do banco de dados foi criptografado e este decifra-lo. O que você forneceu acima não parecem funcionar. No banco de dados é latino-1, Django converte para unicode, mas não posso passá-lo para a função como unicode, mas quando eu tento e codificá-lo para LATIN-1 i ver esse erro.

Respondeu 08/11/2008 em 06:42
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more