2013-09-10 2 views
0

Я смущен о шестнадцатеричном представлении Unicode. У меня есть пример файла с одним математическим символом знака интеграла. Это U + 222B Если я кот файл или отредактируйте его в vi, я получу знак интеграла. Шестнадцатеричный дамп файла показывает, что его содержание в гексагоне составляет 88e2 0aabConfused о представлениях unicode

В python Я могу создать единый символ Юникода и распечатать рендеринг на моем терминале и знак интеграла.

>>> p=u'\u222b' 
>>> p 
u'\u222b' 
>>> print p 
∫ 

Что меня смущает, я могу открыть файл с знаком интеграла в нем, получить интегральный символ, но содержание шестигранной отличается.

>>> c=open('mycharfile','r').read() 
>>> c 
'\xe2\x88\xab\n' 
>>> print c 
∫ 

Один объект Unicode и один является простой строкой, но то, что отношения между двумя шестигранными кодами, по-видимому для того же самого характера? Как бы я вручную преобразовал один в другой?

+1

'0x222b' = 8747 - целое число кодовых точек, которое в Юникоде ассоциировано со знаком интеграла' ∫'. когда вы пишете текст в файл или отправляете его по проводу, он всегда должен быть сериализован для бит - обычно, октеты (байты) являются предпочтительными единицами здесь. серия '0xe2',' 0x88', '0xab' (или' 0b11100010', '0b10001000',' 0b10101011' в двоичном формате) - это кодировка UTF-8 (http://en.wikipedia.org/wiki/UTF- 8) «0x222b». Кстати, три ведущие '1' в первом байте говорят вам, что этот код указан в трех байтах: UTF-8 - это как переменная ширина, так и «синхронизация». – flow

+0

Обязательно: http://bit.ly/unipain – Daenyth

+0

, что битовая ссылка выглядит многообещающей. также следует отметить, что обработка Юникода намного более устойчива в Py3, чем когда-либо в Py2, до такой степени, что этот фактор должен сильно влиять на решение о том, какую версию Python использовать. К сожалению, есть непрочный и продолжающийся разрыв между Py2 и Py3, а поддержка сторонней библиотеки отстает. где Py3 светит, что старые «строки ASCII» исчезли; вы всегда имеете дело с буфером байтов (закодированным) или другим (Unicode) текстом (декодированным). это просто изменилось понятие/называние вещей, но тогда программирование много о концепциях и именовании вещей. – flow

ответ

3

Простая строка кодируется с использованием UTF-8, одного из множества способов представления кодовых точек Unicode в байтах. UTF-8 представляет собой многобайтовое кодирование, которое имеет часто полезную функцию, что является надмножеством ASCII - один и тот же байт кодирует любой символ ASCII в UTF-8 или в ASCII.

В Python 2.x, использовать метод encode на объекте Unicode для кодирования, и decode или unicode конструктор декодировать его:

>>> u'\u222b'.encode('utf8') 
'\xe2\x88\xab' 
>>> '\xe2\x88\xab'.decode('utf8') 
u'\u222b' 
>>> unicode('\xe2\x88\xab', 'utf8') 
u'\u222b' 

print, когда данный аргумент Unicode, неявно кодирует его , На моей системе:

>>> sys.stdout.encoding 
'UTF-8' 

Смотрите этот ответ в течение более длительного обсуждения поведения print «s: Why does Python print unicode characters when the default encoding is ASCII?

Python 3 обрабатывает вещи немного по-другому; изменения задокументированы здесь: http://docs.python.org/3.0/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit

+2

Должен быть прочитан: [Абсолютный минимум Каждый разработчик программного обеспечения абсолютно уверен, должен знать об Unicode и наборах символов (без отговорок!)] (Http://www.joelonsoftware.com/articles/Unicode.html) от Joel Spolsky. – usr2564301

0

ОК, у меня оно есть. Спасибо за ответы. Я хотел посмотреть, как сделать преобразование, а не преобразовывать строку с помощью Python.

преобразование работает таким образом.

Если у вас есть символ юникода, в моем примере есть неотъемлемый символ.

восьмиштырьковый свалка производит

echo -n "∫"|od -x 
0000000 88e2 00ab 

Каждый гекс пары перепутаны, так что на самом деле означает

e288ab00 

Первый шестнадцатеричный символ E. старший бит означает, что это строка Unicode и следующие два биты указывают, что это 3 три байта (16 бит) для представления символа. Первые два бита оставшихся шестнадцатеричных цифр выбрасываются (они означают, что они являются юникодами.) Полный битовый поток

111000101000100010101011 

выбросить первые 4 бита, а первые два бита остальных шестнадцатеричных цифр

0010001000101011 

Повторно выражая это в шестнадцатеричном

222B 

Они у тебя есть это!

+0

«высокий бит означает, что это строка Unicode» не совсем прав. Он размывает линию между использованием символов, которые не были в ASCII, с подробными данными кодировки UTF-8. Точнее, высокий бит означает, что он является частью многобайтовой кодировки; число ведущих 1s до первого 0 сообщает вам общее количество байтов в кодировке (3 в этом случае). У вас есть правильная обработка, но я рекомендую внимательно прочитать Joel on Software essay Jongware, связанную с. Юникод и кодировки - это связанные понятия, но не такие взаимозаменяемые, как подразумевается в этой формулировке. –