Question

ok, mon problème est que j’ai la chaîne '\ 222 \ 222 \ 223 \ 225' qui est stockée en tant que latin-1 dans la base de données. Ce que j’obtiens de django (en l’imprimant) est la chaîne suivante, '& # 226; & # 226; & # 226; & # 226; & # 162;' que je suppose est la conversion UTF de celui-ci. Maintenant, je dois passer la chaîne dans une fonction qui fait cette opération:

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

Je reçois cette erreur:

  

chr () arg pas dans la plage (256)

Si j'essaie de coder la chaîne en tant que latin-1, le message d'erreur suivant s'affiche:

  

Le codec 'latin-1' ne peut pas coder les caractères en position 0-3: ordinal pas   dans la plage (256)

J'ai lu un tas de choses sur le fonctionnement de l'encodage de caractères et il me manque quelque chose parce que je ne l'obtiens pas!

Était-ce utile?

La solution

Votre première erreur 'chr () arg not in range (256)' signifie probablement que vous avez dépassé la valeur, car chr ne peut pas prendre de nombres négatifs. Je ne sais pas ce que l'algorithme de chiffrement est censé faire lorsque le compteur d'entrée + 33 est supérieur à la représentation réelle du caractère, vous devrez vérifier quoi faire dans ce cas.

À propos de la deuxième erreur. vous devez décoder () et non encoder () un objet chaîne classique pour obtenir une représentation correcte de vos données. encode () prend un objet unicode (ceux commençant par u ') et génère une chaîne régulière à afficher ou à écrire dans un fichier. decode () prend un objet string et génère un objet unicode avec les points de code correspondants. Cela se fait avec l’appel unicode () lorsqu’il est généré à partir d’un objet chaîne, vous pouvez également appeler a.decode ('latin-1').

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

Autres conseils

Comme le note Vinko, Latin-1 ou ISO 8859-1 ne comporte pas de caractères imprimables pour la chaîne octale que vous citez. D'après mes notes sur 8859-1, les "contrôles C1 (0x80 - 0x9F) proviennent de l'ISO / CEI 6429: 1992. Il ne définit pas les noms pour 80, 81 ou 99 ". Les noms des points de code sont tels que les énumère Vinko:

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

Le codage UTF-8 correct de ceux-ci est (Unicode, binaire, hex):

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

La petite lettre laïque A avec CIRCUMFLEX est le code ISO 8859-1 0xE2 et, par conséquent, l’Unicode U + 00E2; dans UTF-8, il s’agit de% 11000011% 10100010 ou 0xC3 0xA2.

Le signe central est ISO 8859-1 code 0xA2 et donc Unicode U + 00A2; dans UTF-8, c’est% 11000011% 10000010 ou 0xC3 0x82.

Ainsi, quoi que vous voyiez, vous ne semblez pas voir un encodage UTF-8 de la norme ISO 8859-1. Tout le reste à part, vous ne voyez que 5 octets où il vous faudrait en voir 8.

Ajouté : La partie précédente de la réponse aborde la revendication 'Codage UTF-8', mais ignore le reste de la question, qui dit:

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

Vous ne nous montrez pas réellement comment intCounter est défini, mais s'il incrémente doucement par caractère, tôt ou tard, ' ord (c) - 3 - intCounter - 30 ' sera négatif (et d'ailleurs, pourquoi ne pas combiner les constantes et utiliser ' ord (c) - intCounter - 33 '?), à quel point, chr () est probable se plaindre. Vous devrez ajouter 256 si la valeur est négative ou utiliser une opération de module pour vous assurer que vous disposez d'une valeur positive comprise entre 0 et 255 à transmettre à chr () . Comme nous ne pouvons pas voir comment intCounter est incrémenté, nous ne pouvons pas dire s'il passe de 0 à 255 ou s'il augmente de manière monotone. Si c'est le dernier cas, vous avez besoin d'une expression telle que:

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

où 256 - 33 = 223, bien sûr, et 479 = 256 + 223. Ceci garantit que la valeur transmise à chr () est positive et comprise dans la plage 0..255 pour toute entrée. caractère c et toute valeur d'intCounter (et, comme la fonction mod () ne reçoit jamais d'argument négatif, elle fonctionne également, quel que soit le comportement de mod () lorsque ses arguments sont négatif).

Eh bien, c’est parce qu’il a été chiffré avec un schéma terrible qui ne fait que modifier la commande ord () du caractère par une requête, de sorte que la chaîne sortant de la base de données a été chiffrée et que celle-ci est déchiffrée. Ce que vous avez fourni ci-dessus ne semble pas fonctionner. Dans la base de données, c’est latin-1, django le convertit en unicode, mais je ne peux pas le transmettre à la fonction en tant qu’unicode, mais lorsque j’essaie de l’encoder en latin-1, je vois cette erreur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top