Форум программистов, компьютерный форум CyberForum.ru

Python: научные вычисления

Войти
Регистрация
Восстановить пароль
 
kravam
быдлокодер
1694 / 881 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
#1

Представление символов в юникоде - Python

08.10.2016, 16:48. Просмотров 447. Ответов 3
Метки нет (Все метки)

Друзья! Быть может, не совсем для питона, но в книжке по питону я нашёл такое утверждение. Вот смотрю на него как баран на новые ворота и ничего не могу понять.

Книга "Programming in Python 3, Mark Summerfield". Привожу фотку, так как не могу напечатать нужный символ ("A с кружком вверху"):

И опять. Первый способ представления символа это [0хЕ2, 0x84, ОхАВ]. Это чего вообще? Тут же русским языком написано, что этот символ имеет номер 0x00C5. Всё. Этот символ имеет только ОДИН номер в кодировке UTF-8. Хорошо, написано, что три номера. Хотелось бы эти номера увидеть, то есть прочесть что-то вроде:
символ "A с кружком вверху" представлен номерами такими-то: 0xXXXX, 0xXXXX, 0xXXXX (тремя разными способами).
Но три списка вообще в уныние меня повергают. Это же не три номера, это же три каких-то списка, и что каждый из них представляет- одному Богу известно.

Ну не последовательно же писать символы из списка для получения нужного номера! То есть берём список [0хЕ2, 0x84, ОхАВ], переписываем числа по порядку, получаем 0хЕ284АВ. Это номер для представления символа "A с кружком вверху" в кодировке UTF-8? Минуточку, там всего 0XFFFF символов может быть представлено... Сижу, гадаю, в общем.

Так как же получить с помощью представленных списков символ "A с кружком вверху"? Спасибо. кто откликнется.
Миниатюры
Представление символов в юникоде  
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.10.2016, 16:48
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Представление символов в юникоде (Python):

Представление символов юникода - Python
print (hex(ord('!'))) # Why is output 0x21 ? print ('\u0021') # output is '!' print ('\u0x21') # don't work Почему в первой...

Получить внешние данные не в Юникоде - Python
Получаю внешние данные в виде \u003c\u003f\u0078\u006d... Преобразую и записываю файл: f1 = open("1.xml", "w") f1.write(unicode(data,...

Как вывести строки в юникоде из кортежа в читаемом виде? - Python
Извлекаю данные из файла, пробую вывести их на экран, выводится все нормально. После сортирую эти данные и добавляю в список, принтую...

Графическое представление числа - Python
Пример взят из книги Саммерфильда. Нужно чтобы какое-либо число (допустим 41072819) представлялось в виде звездочек, но как после того как...

Код в юникоде надстрочных и подстрочных символов, введенных с клавиатуры в richtextedit - Delphi
Есть richtextedit, куда пользователь вводит текст, в котором могут быть надстрочные и подстрочные символы. Вопрос в следующем: допустим,...

Двоичное представление символов - C++
Проблема такая: я прогаю скремблер, и проблема в том, что буквы при переводе дают семизначное двоичное число, а символы - шестизначное. И...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
vrm2
242 / 149 / 32
Регистрация: 03.12.2015
Сообщений: 238
Завершенные тесты: 1
09.10.2016, 11:10 #2
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Если не ошибаюсь, то примерно так:

Сначала придумали обычный Юникод с кодами до 0xFFFF. И в нем есть символ Å, который имеет код 0x00C5.

Чтобы хранить текст Юникод начали кодировать символы "в лоб", двумя байтами (UTF-16).

Потом поняли, что слишком много тратится байт (по два на символ) и придумали UTF-8, в котором коды 0-127 из Юникода представлены в виде одного байта со значениями от 0 до 127. А вот другие символы Юникода кодируются уже несколькими байтами (до 6 байт). Т.е. тексты на анлийском стали занимать меньше места (т.к. английские буквы кодируются одним байтом), а вот другие тексты стали чуть длиннее.

Набор байт, которые ты видишь это код UTF-8 в БИТАХ которого закодирован код Юникод. Как расшифровать - см. страницу вики UTF-8.

Потом еще хуже. Решили количество символов в Юникоде расширить. Сейчас их больше, чем 0xFFFF.
http://unicode-table.com/ru

Пришлось и UTF-16 переделывать из двубайтной кодировки в динамичную - то два байта, то три байта.
А "в лоб" коды Юникоды хранятся сейчас только в UTF-32 (четыре байта на символ), без всякого дополнительного кодирования.

Добавлено через 1 час 0 минут
Python
1
2
3
4
5
6
7
8
9
10
11
12
>>> bytes([0xe2, 0x84, 0xab]).decode('utf-8')
'A'
>>> bytes([0xc3, 0x85]).decode('utf-8')
'A'
>>> bytes([0x41, 0xcc, 0x8a]).decode('utf-8')
'A'
>>> '\u00c5'.encode('utf-8')
b'\xc3\x85'
>>> '\u00c5'.encode('utf-16')
b'\xff\xfe\xc5\x00'
>>> '\u00c5'.encode('utf-32')
b'\xff\xfe\x00\x00\xc5\x00\x00\x00'
Добавлено через 14 часов 0 минут
Один и тот же символ Unicode можно закодировать разными способами в UTF-8.
Но правильным считается самый короткий, а остальные варианты (называются overlong sequences) использоваться не должны.
kravam
быдлокодер
1694 / 881 / 44
Регистрация: 04.06.2008
Сообщений: 5,441
10.10.2016, 18:00  [ТС] #3
Я разобрался почему

1) 0xe2, 0x84, 0xab это символ "A с кружком вверху"
2) 0xc3, 0x85 это символ "A с кружком вверху"

Но почему 0x41, 0xcc, 0x8a это символ "A с кружком вверху", я понять не могу. То есть символ "A с кружком вверху" представлен тремя байтами. Зададимся вопросом- а каким должен быть первый байт? Прочтём здесь:

Количество байт, которое отводится под символ, всегда равно количеству идущих подряд старших бит со значением 1 в первом байте. Эти биты всегда завершаются битом со значением 0
То есть если символ представлен тремя байтами, то независимо ни от чего, первые 4 бита первого байта такие: 1110. А на самом деле 0x41, 0xcc, 0x8a это

010000011100110010001010

Первые 4 бита НЕ 1110, вот что странно! Почему так?
vrm2
242 / 149 / 32
Регистрация: 03.12.2015
Сообщений: 238
Завершенные тесты: 1
10.10.2016, 21:41 #4
Цитата Сообщение от kravam Посмотреть сообщение
Первые 4 бита НЕ 1110, вот что странно! Почему так?
Потому что это специальная последовательность из двух частей, которые объединились в один символ юникода.

01000001 - это обычный символ A

11001100 10001010 - специальный знак - кружок (диакритический знак), который влияет на другие буквы (код U+030A)

Цитата из вики:
Юникод позволяет создавать дополнительные сочетания любых букв с надстрочным кружком, набирая после них код для надстрочного кружка (U+030A)

Поэтому два таких символа идущих подряд дают "А с кружочком вверху"
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.10.2016, 21:41
Привет! Вот еще темы с ответами:

Двоичное представление символов ASCII - C++
например дана последовательность: 0110100001101001 где h=01101000 i=01101001 ] numeric=0110100001101001 как сделать что то вроде...

Вывести двоичное представление суммы символов - Assembler
В строку ввести последовательность "чисел"(10 функция). Вывести двоичное представление суммы символов ассемблер

Конвертировать машинное представление float в строку из 4 символов - C++
Допустим, есть переменная X типа float, имеющая значение... да хотя бы -3.14. Машинным представлением этого числа являются четыре байта....

Visual Prolog. Представление символов и строк, операции над строками. - Prolog
1. Разработать программу реализующую различные способы представления символов и строк, а также выполнения операций над строками. 2....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
10.10.2016, 21:41
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru