Попытка показать типичную ошибку кодирования / декодирования между MacRoman и Latin1

Я хотел бы показать своим студентам результат открытия в виде macroman/latin1 файла, закодированного как latin1/macroman [соответственно]:

>>> s = u"Tout condamné à mort aura la tête tranchée."
>>> print s.encode("latin1").decode("macroman")
Tout condamnÈ ‡ mort aura la tÍte tranchÈe.
>>> print s.encode("macroman").decode("latin1")
Tout condamn  mort aura la tte tranche.

Но я озадачен тем фактом, что второе преобразование не показывает никакого видимого не ASCII символа. Разве macroman и latin1 не должны быть байтовыми символами <->?

NB: Это не связано с Python, так как я могу воспроизвести поведение с помощью текстового редактора.

1 ответ

Решение

"Latin1" является неопределенным термином и может относиться к ISO Latin 1 (ISO 8859-1) или Windows Latin 1 (windows-1252). Разница заключается в том, что в ISO Latin 1 байты от 0x80 до 0x9F обозначены как управляющие символы (редко используются), тогда как в Windows Latin 1 большинство из них определены как графические символы (знаки препинания и некоторые не-латинские буквы латинского алфавита) и несколько оставлено неопределенным.

Когда вы берете, например, букву "é" и кодируете Latin1 (либо в кодировке Latin1), вы получаете байт 0xE9. Если вы затем интерпретируете этот байт как закодированный MacRoman, как вы, кажется, делаете, вы получите символ "È". Вот почему вы получаете "condamnÈ".

Но если вы возьмете букву "é" в кодировке MacRoman, это будет 0x8E. При интерпретации этого байта как данных Latin1 кодировки Latin1 различаются. В ISO Latin 1 это управляющий символ SINGLE SHIFT TWO (U+008E); в Windows Latin 1 это "Ž" LATIN CAPITAL LETTER Z с CARON (U+017D). Очевидно, что ваш код рассматривает Latin1 как ISO Latin 1. Поскольку U + 008E обычно не имеет значения, назначенного ему в большинстве программ, он обычно игнорируется при рендеринге, но в этом случае явно отображается как пробел.

Другие случаи аналогичны: MacRoman "à" равен 0x88, а MacRoman "ê" равен 0x90, оба значения, входящие в управляющий символ, соответствуют ISO 8859-1.

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