Краткий ответ
Используйте cp437 в качестве кодировки для некоторого ретро-развлечения для DOS. Все байтовые значения, большие или равные 32 десятичным, кроме 127, отображаются в отображаемые символы в этой кодировке. Затем используйте cp037 в качестве кодировки для действительно трипового времени. А затем спросите себя, как вы действительно знаете, какой из них, если какой-либо из них, является «правильным».
Длинный ответ
Есть кое-что, что вы должны отучить: абсолютная эквивалентность байтовых значений и символов.
Многие основные текстовые редакторы и средства отладки сегодня, а также спецификация языка Python подразумевают абсолютную эквивалентность между байтами и символами, хотя в действительности их не существует. Неверно, что 74 6f 6b 65 6e
является"токеном". Это соответствие действительно только для ASCII-совместимых кодировок символов. В EBCDIC, который все еще довольно распространен сегодня, «токен» соответствует байтовым значениям a3 96 92 85 95
.
Поэтому, хотя интерпретатор Python 2.6 с радостью оценивает 'text' == u'text'
как True
, этого не следует делать, поскольку они только эквивалентны в предположении ASCII или совместимой кодировки, и даже тогда они должны не считается равно . (По крайней мере, '\xfd' == u'\xfd'
- это False
и вы получите предупреждение за попытку.) Python 3.1 оценивает 'text' == b'text'
как False
. Но даже принятие этого выражения интерпретатором подразумевает абсолютную эквивалентность байтовых значений и символов, потому что выражение b'text'
используется для обозначения «строки байтов, которую вы получаете, когда применяете кодировку ASCII к 'text'
» с помощью переводчик.
Насколько я знаю, каждый широко распространенный сегодня язык программирования подразумевает неявное использование кодировки символов ASCII или ISO-8859-1 (Latin-1) где-то в своем дизайне. В Си тип данных char
действительно является байтом. Я видел одну виртуальную машину Java 1.4, где конструктор java.lang.String(byte[] data)
предполагал кодировку ISO-8859-1. Большинство компиляторов и интерпретаторов допускают кодирование исходного кода в кодировке ASCII или ISO-8859-1 (некоторые позволяют вам его изменить). В Java длина строки действительно равна длине кодовой единицы UTF-16, что, возможно, неправильно для символов U+10000
и выше. В Unix имена файлов - это байтовые строки, интерпретируемые в соответствии с настройками терминала, что позволяет вам open('a\x08b', 'w').write('Say my name!')
.
Итак, мы все были обучены и обусловлены инструментами, которым мы научились доверять, полагая, что «А» - это 0x41. Но это не так. «A» - это символ, а 0x41 - это байт, и они просто не равны.
Как только вы станете просветленным в этом вопросе, у вас не будет проблем с решением вашей проблемы. Вам просто нужно решить, какой компонент в программном обеспечении принимает кодировку ASCII для этих байтовых значений и как изменить это поведение или убедиться, что вместо него появляются другие байтовые значения.
PS: фразы "расширенный ASCII" и "набор символов ANSI" являются неправильными.