Хорошо, поэтому моя проблема в том, что у меня есть строка '\ 222 \ 222 \ 223 \ 225', которая хранится как latin-1 в базе данных. Я получаю от django (распечатывая его) следующую строку «ââââ», которая, как я предполагаю, является ее преобразованием в UTF. Теперь мне нужно передать строку в функцию, которая выполняет эту операцию:
strdecryptedPassword + chr(ord(c) - 3 - intCounter - 30)
Я получаю такую ошибку:
chr() arg not in range(256)
Если я попытаюсь сначала закодировать строку как latin-1, я получу эту ошибку:
'latin-1' codec can't encode characters in position 0-3: ordinal not in range(256)
Я прочитал кучу о том, как работает кодировка символов, и кое-что мне не хватает, потому что я просто не понимаю!






Ваша первая ошибка «chr () arg not in range (256)», вероятно, означает, что вы занижены значением, потому что chr не может принимать отрицательные числа. Я не знаю, что должен делать алгоритм шифрования, когда inputcounter + 33 больше, чем фактическое представление символа, вам нужно будет проверить, что делать в этом случае.
Насчет второй ошибки. вы должны decode (), а не encode () обычный строковый объект, чтобы получить правильное представление ваших данных. 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)
Это потому, что он был зашифрован с помощью какой-то ужасной схемы, которая просто изменяет ord () символа по некоторому запросу, поэтому строка, выходящая из базы данных, была зашифрована, и это расшифровывает ее. То, что вы указали выше, похоже, не работает. В базе данных это latin-1, django преобразует его в unicode, но я не могу передать его функции как unicode, но когда я пытаюсь закодировать его в latin-1, я вижу эту ошибку.
и для c в u '\ 222 \ 222 \ 223 \ 225': print chr (ord (c) - 33) также работает. Он также работает со строковыми объектами.
Как отмечает Винко, Latin-1 или ISO 8859-1 не имеют печатаемых символов для восьмеричной строки, которую вы цитируете. Согласно моим примечаниям для 8859-1, «Элементы управления C1 (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
ЛАТИНСКАЯ СТРОЧНАЯ БУКВА A С CIRCUMFLEX - это код ISO 8859-1 0xE2 и, следовательно, Unicode U + 00E2; в UTF-8 это% 11000011% 10100010 или 0xC3 0xA2.
ЦЕНТРАЛЬНЫЙ ЗНАК - это код 0xA2 ISO 8859-1 и, следовательно, 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(), когда ее аргументы отрицательны).
Все это не имеет значения, поскольку он использует доморощенный алгоритм шифрования. Эти байты не предназначены для печати перед процедурой дешифрования. Вот почему я удалил информацию, которую вы здесь поместили.
@Vinko: Похоже, я имел дело с первым абзацем, а не с остальными. Добавлю немного материала. Я думаю, что вижу проблему (не обязательно «проблему», но ....).
Пожалуйста, поместите фактический код с реальным примером строки, потому что u '\ 222 \ 222 \ 223 \ 225'.encode (' latin-1 ') работает для меня