Вопрос

Хорошо, моя проблема в том, что у меня есть строка '\ 222 \ 222 \ 223 \ 225', которая хранится как datin-1 в БД. Что я получаю от django (печатая его), это следующая строка: '& # 226; & # 226; & # 226; & # 226; & # 162;' я предполагаю, что это UTF-преобразование. Теперь мне нужно передать строку в функцию, которая выполняет эту операцию:

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

Я получаю эту ошибку:

  

chr () arg вне диапазона (256)

Если я сначала пытаюсь закодировать строку как латиница-1, я получаю эту ошибку:

  

кодек «latin-1» не может кодировать символы в позиции 0-3: порядковый номер не   в диапазоне (256)

Я много читал о том, как работает кодировка символов, и мне чего-то не хватает, потому что я просто не понимаю!

Это было полезно?

Решение

Ваша первая ошибка 'chr () arg not in range (256)', вероятно, означает, что вы недооценили значение, потому что chr не может принимать отрицательные числа. Я не знаю, что должен делать алгоритм шифрования, когда значение inputcounter + 33 больше, чем фактическое представление символов, вам придется проверить, что делать в этом случае.

О второй ошибке. Вы должны декодировать (), а не кодировать () обычный строковый объект, чтобы получить правильное представление ваших данных. encode () принимает объект Unicode (те, которые начинаются с u ') и генерирует обычную строку для вывода или записи в файл. decode () принимает строковый объект и генерирует объект Unicode с соответствующими точками кода. Это делается с помощью вызова unicode (), когда он генерируется из строкового объекта, вместо этого вы также можете вызвать 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)

Другие советы

Как отмечает Винко, в Latin-1 или ISO 8859-1 нет печатных символов для восьмеричной строки, которую вы цитируете. Согласно моим примечаниям для 8859-1, «C1 Control (0x80 - 0x9F) взяты из ISO / IEC 6429: 1992. Он не определяет имена для 80, 81 или 99 ". Имена кодовых точек соответствуют спискам Винко:

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

Правильная кодировка UTF-8 для них (Unicode, двоичный, шестнадцатеричный):

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

МАЛЕНЬКОЕ ПИСЬМО А ЛАТИНЫ С CIRCUMFLEX - ISO 8859-1, код 0xE2 и, следовательно, Unicode U + 00E2; в UTF-8 это% 11000011% 10100010 или 0xC3 0xA2.

CENT SIGN - это ISO 8859-1, код 0xA2 и, следовательно, Unicode U + 00A2; в UTF-8 это% 11000011% 10000010 или 0xC3 0x82.

Итак, что бы вы ни видели, вы, похоже, не видите кодировку UTF-8 ISO 8859-1. Все остальное, кроме 5 байт, где вы должны увидеть 8.

Добавлено : Предыдущая часть ответа посвящена утверждению «кодировка UTF-8», но игнорирует остальную часть вопроса, которая гласит:

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

На самом деле вы не показываете нам, как определяется intCounter, но если он будет постепенно увеличиваться для каждого символа, рано или поздно « ord (c) - 3 - intCounter - 30 » будет отрицательным (и, между прочим, почему бы не объединить константы и использовать ' ord (c) - intCounter - 33 '?), и в этот момент chr () вероятен жаловаться. Вам нужно добавить 256, если значение отрицательное, или использовать операцию модуля, чтобы убедиться, что у вас есть положительное значение от 0 до 255 для передачи в chr () . Поскольку мы не можем видеть, как увеличивается intCounter, мы не можем определить, будет ли он циклически изменяться от 0 до 255 или монотонно ли он увеличивается. Если последнее, то вам нужно выражение, такое как:

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

где 256 - 33 = 223, конечно, и 479 = 256 + 223. Это гарантирует, что значение, переданное в chr () , положительное и находится в диапазоне 0..255 для любого ввода символ c и любое значение intCounter (и, поскольку функция mod () никогда не получает отрицательный аргумент, она также работает независимо от того, как mod () ведет себя, когда ее аргументы отрицательный).

Ну, это потому, что он был зашифрован по какой-то ужасной схеме, которая просто изменяет ord () символа по какому-либо запросу, поэтому строка, выходящая из базы данных, была зашифрована, и это расшифровывает ее. То, что вы указали выше, похоже, не работает. В базе данных это latin-1, django преобразует его в unicode, но я не могу передать его функции как unicode, но когда я пытаюсь закодировать его в latin-1, я вижу эту ошибку.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top