Проблемы преобразования UTF-8 latin-1, python django

Хорошо, поэтому моя проблема в том, что у меня есть строка '\ 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)

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

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
0
10 915
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Ваша первая ошибка «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, я вижу эту ошибку.

Пожалуйста, поместите фактический код с реальным примером строки, потому что u '\ 222 \ 222 \ 223 \ 225'.encode (' latin-1 ') работает для меня

Vinko Vrsalovic 08.11.2008 08:47

и для c в u '\ 222 \ 222 \ 223 \ 225': print chr (ord (c) - 33) также работает. Он также работает со строковыми объектами.

Vinko Vrsalovic 08.11.2008 08:49

Как отмечает Винко, 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 Vrsalovic 08.11.2008 09:31

@Vinko: Похоже, я имел дело с первым абзацем, а не с остальными. Добавлю немного материала. Я думаю, что вижу проблему (не обязательно «проблему», но ....).

Jonathan Leffler 08.11.2008 09:42

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