Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Всё, что вы хотели знать про Unicode, но боялись спросить

Всё, что вы хотели знать про Unicode, но боялись спросить

Семён Факторович (HDsoft) рассказывает про Unicode и историю кодировок.

«Что лучше: UTF-8, UTF-16 или UTF-32? Сколькими байтами кодируется одна буква в UTF-16? Почему использование слова «буква» в предыдущем вопросе некорректно? Почему правильно реализовать strlen() или функцию переворачивания строки вовсе не так просто, как кажется? И почему, чёрт возьми, при попытке вывести русские буквы в консоль я вижу кракозябры?

В лекции будут даны ответы на эти и некоторые другие вопросы о Unicode. Бонусом мы расскажем краткую историю кодировок от начала времен (точнее, от времен DOS CP 866 и KOI8-R)»

Видеозапись: http://www.youtube.com/watch?v=8HRq_-c5fn0

Подробности: http://techtalks.nsu.ru

E51d363aa46f4d059d54a15e0bcd8e6f?s=128

Tech Talks @NSU

October 28, 2014
Tweet

Transcript

  1. Всё, что вы хотели знать о Unicode, но боялись спросить

    性交 Семён Факторович vk.com/sfactor lazeez
  2. Кто здесь? • Семён Факторович • АФТИ ФФ (2007), магистратура

    ФИТ (2009) • НГУ, HDsoft
  3. ASCII ANSI OEM KOI-8 Win-1251 UTF-8 Unicode UTF-16 UTF-32 UCS-2

    DOS 866
  4. ASCII American Standard Code for Information Interchange 1 символ =

    1 байт
  5. ASCII

  6. ASCII

  7. ASCII Σε γνωρίζω από την κόψη του σπαθιού την τρομερή,

    Cъешь ещё этих мягких французских булок, да выпей же чаю
  8. ASCII Non-latin characters находятся в верхней части таблицы (128-255)

  9. ASCII

  10. Codepages • Windows Codepages, ANSI codepages • ... • 1251

    - Cyrillic • 1252 - Latin • 1253 - Greek • 1255 - Hebrew • ...
  11. Русскому языку не повезло

  12. • Windows 1251 • DOS (OEM 866) • KOI-8 •

    MacCyrillic Русскому языку не повезло
  13. None
  14. None
  15. None
  16. None
  17. Win 1251 KOI-8 В о п р о с 194

    238 239 240 238 241 б Н О П Н Я
  18. None
  19. None
  20. None
  21. (KOI-8 character) && 0b01111111 = (transliterated character) KOI-8 -128 В

    о п р о с 247 207 208 210 207 211 119 79 80 82 79 83 w O P R O S
  22. None
  23. ASCII-based encodings • 1 буква = 1 байт • Константная

    индексация • 100% error tolerance
  24. ASCII-based encodings Главное — выбрать кодировку

  25. ASCII: две проблемы • Невозможность использовать несколько non-latin алфавитов в

    одном тексте • Иероглифическое письмо
  26. Unicode • Единый стандарт • 1 буква = 2 байта

    • 65536 символов должно хватить всем
  27. Unicode: the basics Давайте сведем все (абсолютно все!) символы в

    одну таблицу
  28. ... ... ... U+0061 a Latin Small Letter A U+0062

    b Latin Small Letter B ... ... ... U+00C7 Ç Latin Capital letter C with cedilla ... ... ... U+0429 Щ Cyrillic Capital Letter Shcha ... ... ... U+05E9 ש Hebrew Letter Shin ... ... ... U+2658 ♘ White Chess Knight ... ... ...
  29. None
  30. None
  31. Unicode: the basics • Элемент таблицы — code point •

    Code (U+0061) • Name (Latin Small Letter A)
  32. Unicode: the basics • codepoint ≠ символ • “abstract character”

  33. Х 1 abstract character, 1 code point U+0425 Cyrillic Capital

    Letter Ha
  34. é 1 abstract character, 2 code points U+0065 Latin Small

    Letter E U+02CA Modifier Letter Acute Accent
  35. é 1 abstract character, 1 code point U+00E9 Latin Small

    Letter E with Acute
  36. œ 2 буквы! 1 abstract character, 1 code point U+0151

    Latin Small Ligature OE
  37. Unicode: the ultimate solution?

  38. Unicode: the caveats • Latin Capital letter H, U+0048 •

    strlen(“Hello world”) == 0
  39. Unicode: the caveats • 65536 code points недостаточно • Одних

    иероглифов только 74500! • Сейчас стандарт описывает 109449 code points
  40. UTF-8 Variable-length encoding спешит на помощь!

  41. UTF-8 1 byte 0xxxxxxx 2 bytes 110xxxxx 10xxxxxx 3 bytes

    1110xxxx 10xxxxxx 10xxxxxx 4 bytes 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 5 bytes 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 6 bytes 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  42. UTF-8 • 1-6 байт • ASCII compatible: английский текст в

    ASCII идентичен UTF-8
  43. UTF-8 • strlen(“Hello world”) == 11 • strlen(“Привет”) == 12

    • Линейная индексация • Простая синхронизация
  44. UTF-16 • Внезапно, тоже variable-length • 2 или 4 байта

    • Surrogate pairs
  45. UCS-2 • “The original Unicode” • Всегда 2 байта

  46. UTF-32 • Всегда 4 байта • Ура, константная индексация!

  47. Endianness problem • UTF-16: 2 или 4 байта • UTF-16LE,

    UTF-16BE
  48. Endianness problem • Byte order mark, BOM • Ставится в

    начале строки • U+FEFF, Zero-width non-breaking space • Читаем 0xFEFF или 0xFFFE и определяем endianness
  49. Endianness problem • Byte order mark, BOM • При отсутствии

    BOM считаем, что строка big-endian • Большинство софта по умолчанию ожидает little-endian
  50. Endianness problem • А можно просто искать вхождения 0x0020 или

    0x2000 • U+0020 Space character
  51. Endianness problem • В UTF-8 и UTF-32 порядок байт всегда

    однозначный • Но Microsoft использует BOM для UTF-8
  52. Endianness problem • В UTF-8 и UTF-32 порядок байт всегда

    однозначный • Но Microsoft использует BOM для UTF-8
  53. Зоопарк • ASCII • UTF-8 • UTF-16 • UCS-2 •

    UTF-32
  54. Windows • Смесь ASCII и UTF-16 • SetWindowTextA() и SetWindowTextW()

    • #define UNICODE
  55. Linux, OS X • UTF-8

  56. Работа с текстом • Чтение текста (из файла, из сокета,

    из БД...) • Внутреннее хранение и обработка • Вывод текста (в файл, на экран, в сокет, в API-вызов)
  57. Работа с текстом 1. Определитесь с внутренним представлением текста (UTF-8,

    UTF-16, UTF-32) 2. Убедитесь, что вы правильно работаете с выбранной кодировкой 3. При чтении текста конвертируйте его во внутреннее представление 4. При выводе текста конвертируйте его в нужную кодировку
  58. Работа с текстом 2. Убедитесь, что вы правильно работаете с

    выбранной кодировкой Длина строки? Индексация? Регулярные выражения?
  59. résumé [ r e ˊ s u m e ˊ]

    strlen(“résumé”): 6 или 8 “résumé”[1]: e или é reverse(“résumé”): émusér или ˊemuśer
  60. Внутреннее представление строк • What matters is internal representation •

    Почитайте мануал по работе со строками в вашем языке • Помните о кодировке при получении и выводе текста
  61. Работа со строками • Длина строки? • Количество байт •

    Количество символов • Отображение на экране • Перемещение курсора
  62. Лигатуры ffl • 1 code point (U+FB04) • 3 буквы

    (F, F, L) • 1 позиция курсора • Backspace не стирает символ, а превращает его в “FF”
  63. Dynamic composition

  64. Привет́ x̃

  65. é U+0065 Latin Small Letter E U+02CA Modifier Letter Acute

    Accent или U+00E9 Latin Small Letter E with Acute?
  66. Unicode normalization • Композиция: комбинированные символы собираются в один •

    Декомпозиция: сложные символы разбираются на комбинации
  67. Unicode normalization • Понятие эквивалентности символов • Ничего придумывать не

    нужно: все описано в стандарте Unicode • Реализовывать тоже ничего не нужно: http://icu-project.org/
  68. Unicode normalization

  69. Unicode normalization

  70. Что еще бывает • Collations: • Ç C ç c:

    кто старше? • Case mapping • Турецкий язык: i => İ • RTL, BiDi
  71. Что еще бывает • Все уже реализовано за нас: •

    http://icu-project.org/
  72. Подытожим • UTF-8 FTW (utf8everywhere.org) • Помните о внутреннем представлении

    • Помните о кодировках при вводе/выводе информации • Не пишите ничего сами: ICU project
  73. Всё, что вы хотели знать о Unicode, но боялись спросить

    性交 Семён Факторович vk.com/sfactor lazeez