Русскоязычное программирование

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Русскоязычное программирование » система типов » Строки, хранение и обработка


Строки, хранение и обработка

Сообщений 1 страница 8 из 8

1

Итаг, допустим у нас есть файл в UTF-8.
Начинается он с трёхбайтового маркера (который всегда одинаковый).
    The UCS character U+FEFF "ZERO WIDTH NO-BREAK SPACE" is also known informally as "BYTE ORDER MARK" (abbreviated "BOM").
    Unicode 3.2 adds a new character, U+2060 "WORD JOINER", with exactly the same semantics and usage as U+FEFF except for the signature function

В файле используется какая-то там алгоритмическая кодировка (где бы про неё прочитать? - описанная в RFC3629)
После раскодировки в памяти образуются code points (всегда ли они двухбайтовые?).
Один символ (глиф) может занимать несколько code points (склеиваться из нескольких символов)

В русском языке это важно знать для простановки ударения над буквами.

Вот, допустим, пишите вы текстовый редактор и надо передвинуться на глиф влево.
Внезапно оказывается, что этот глиф, ну например буква "ы́". Нетрудно посчитать,
что передвигатся надо на два кодепоинта или 4 байта.
Кто только и главное как это считает?

Отредактировано Лис (2017-03-26 13:01:53)

0

2

Лис написал(а):

где бы про неё прочитать?

https://habrahabr.ru/post/138173/

Символы с кодами от 128 кодируются 2-мя байтами, с кодами от 2048 — 3-мя, от 65536 — 4-мя.
0x00000000 — 0x0000007F: 0xxxxxxx
0x00000080 — 0x000007FF: 110xxxxx 10xxxxxx
0x00000800 — 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
0x00010000 — 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

ISO/IEC 10646-1 defines a large character set called the Universal Character Set (UCS)
   ISO/IEC 10646:2014,  198 CHF (Швейцарский Франк)
     http://www.unicode.org/L2/L2014/14142-1 … -pdam2.pdf
2003-11, RFC3629

тест:
http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt

exploit has actually been used in a widespread virus attacking Web servers in 2001
%)

Отредактировано Лис (2017-03-26 12:54:52)

0

3

Как же в памяти с двухбайтовыми символами (как например в Java, C# и COM с его BSTR) хранят codepoint'ы, которые в два байта не влезают?

UTF-16 defines each code point in the Unicode set using either 1 or 2 WIDE CHAR

RFC2781

Заколдовывание:

1) If U < 0x10000, encode U as a 16-bit unsigned integer and
      terminate.

2) Let U' = U - 0x10000. Because U is less than or equal to 0x10FFFF,
      U' must be less than or equal to 0xFFFFF. That is, U' can be
      represented in 20 bits.

3) Initialize two 16-bit unsigned integers, W1 and W2, to 0xD800 and
      0xDC00, respectively. These integers each have 10 bits free to
      encode the character value, for a total of 20 bits.

4) Assign the 10 high-order bits of the 20-bit U' to the 10 low-order
      bits of W1 and the 10 low-order bits of U' to the 10 low-order
      bits of W2. Terminate.

U' = yyyyyyyyyyxxxxxxxxxx
   W1 = 110110yyyyyyyyyy
   W2 = 110111xxxxxxxxxx

Расколдовывание:

1) If W1 < 0xD800 or W1 > 0xDFFF, the character value U is the value
      of W1. Terminate.

2) Determine if W1 is between 0xD800 and 0xDBFF. If not, the sequence
      is in error and no valid character can be obtained using W1.
      Terminate.

3) If there is no W2 (that is, the sequence ends with W1), or if W2
      is not between 0xDC00 and 0xDFFF, the sequence is in error.
      Terminate.

4) Construct a 20-bit unsigned integer U', taking the 10 low-order
      bits of W1 as its 10 high-order bits and the 10 low-order bits of
      W2 as its 10 low-order bits.

Что я думаю по этому поводу?
Может имеет смысл считывать файл, переводить всё во внутреннюю кодировку, работать с внутренней кодировкой (вероятно однобайтной), а при вызовах API конвертировать в UTF-16 и обратно? Вызовы API могут быть, например при рисовании строк, когда надо в шрифте глиф искать.

Отредактировано Лис (2017-03-26 13:21:10)

0

4

Что мы знаем про преобразование Барроуза-Уилера (Burrows-Wheeler Transform, BWT) ?

"in general it needs fairly long samples (a few kilobytes at least) of appropriate data (such as text)."
ну, мне кажется, это скорее только для компрессоров. Строки в программе редко бывают по несколько килобайтов.

А вот Хаффман с инструкцией BEXTR от новых процессоров мог бы сработать. Жаль, что у меня процессор старый.

Отредактировано Лис (2017-03-26 13:32:30)

0

5

В кумире есть две функции для работы с юникодом:

юникод(с)
    Код символа в таблице Юникод
символ2(х)
   Символ таблицы Юникод

0

6

Лис написал(а):

В файле используется какая-то там алгоритмическая кодировка (где бы про неё прочитать? - описанная в RFC3629)
После раскодировки в памяти образуются code points (всегда ли они двухбайтовые?).

Алгоритм кодирования UTF-8 вы сами описали ниже. На его алгоритмичности основано автоматическое распознавание, поскольку BOM для UTF-8 не обязательна, по крайней мере на практике. Если кодировка не указана внешней средой, большинство редакторов и браузеров пытаются раскодировать текст как UTF-8, а если не получается, считают его какой-то страховочной (fallback) кодировкой. Этот поведение я реализовал у себя в CoreLite, константа soFromTheWild кагбэ намекает. Строки CoreLite будут использоваться средой Кантора.

Кодовые точки Юникода -- абстрактное, математическое понятие. Они как числа в математике -- не имеют размера. При переходе от математики к байтам и словам появляются UTF, описывающие хранение абстрактных кодовых точек в виде конкретных битов и байтов. Если кодировать кодовые точки без преобразования, для полного охвата нужны 4 байта. Сейчас даже в Рунете можно встретиться с "верхним Юникодом" -- в моде эмодзи.

На практике чаще всего используется UTF-16. Юникод устроен таким образом, что в BMP (первых 64K точках) размещены символы современных земных языков, а всё что выше -- исторические и вымершие языки и иероглифы, плюс поп-культура вроде эмодзи. Про выбор кодировки для компилятора написано у Юрия, я с ним согласен. Если вы не создаете диалект Брейнфака на основе смайликов, UTF-16 подойдет и вам.

На мой вкус, с UTF-16 намного проще работать: разбор строки идет по 16-битным словам, и экзотика вроде эмодзи успешно пропускается, будучи закодированной в виде суррогатов, дополнительный код для их обхода не нужен. А в UTF-8, как мне кажется, придется раскодировать строку по ходу разбора, чтобы нормально отработать регистр или разложение символов (NFC/NFKC/...).

0

7

Предлагаю сценарий: каждый процесс ведёт свою внутреннюю кодировку, какая ему нравится. При обмене с операционной системой и записи на диск, программа выбирает формат сохранения, например UTF-8 (или формат вывода на экран - UTF-16) и конвертирует.

Юрий написал(а):

Использовать 8-битные кодировки слишком непрактично по многим причинам

по каким. Мы хотим полный список,

Юрий написал(а):

Символы этой кодировки должны иметь постоянный размер (в байтах, конечно, а не в пикселах).

лично я согласен и на биты. Главное, чтобы можно было позиционироваться по индексу. Современные процессоры позволяют (максимум что грозит - небольшая задержка, если символ переходит через границу линии кеша). Таким образом и 10 битовых символов хватит за глаза. Мне самому хватит и восьми.

Все остальные требования из списка Юрия выполняются, внутренняя кодировка их проходит.

Хочется добавить биты-флаги? Пожалуйста! Это внутреннее дело программы.

Использую кодировки, в которых символы кодируются переменным числом байтов, мы лишаемся возможности обращаться к строкам, используя порядковый номер символа: string[i]. Чтобы узнать количество символов в строке, нужно провести её разбор.

Любой русский символ со знаком ударения (основным или вспомогательным) в кодировке UTF-16 ломает этот алгоритм доступа по индексу.

Кроме того, решение Юрия заведомо несовместимо с Юникодом (Юрий сознательно отбрасывает эмоджи).

А моё учитывает любые символы. Программа читает входной поток, отбирает используемые символы, перекодирует, расставляет флаги и создаёт внутреннюю кодировку. Делать это будет библиотека рантайма, так что трудностей прикладным программам это не добавит.

При этом есть отвязка от Unicode. Кинули они Корею на их диапазон символов. Корейцы мучались. А тут всё будет хорошо. Просто добавится поддержка ещё одного стандарта внешнего представления. Хочется нестандартные символы, которых нет в Unicode - пожалуйста.

Отредактировано Лис (2017-03-26 22:44:17)

0

8

А как быть с отладкой? В дампе памяти ведь окажется строка во внутренней кодировке.

0


Вы здесь » Русскоязычное программирование » система типов » Строки, хранение и обработка