ПО, ЭВМ и АСУ из Таможенного Союза

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

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


Вы здесь » ПО, ЭВМ и АСУ из Таможенного Союза » обработка текста » Строки, хранение и обработка


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

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

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/exam … 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

9

🏳️‍🌈
👩‍❤️‍💋‍👩

LOR: c++ и utf-8

Отредактировано Лис (2018-08-16 17:04:34)

0

10

⚕️

    U+1F469 WOMAN
    U+200D ZERO WIDTH JOINER
    U+2695 STAFF OF AESCULAPIUS
    U+FE0F VARIATION SELECTOR-16

«белая женщина-врач», являющейся комбинацией символов «женщина» (U+1F469), «модификатора — белый цвет» (U+1F3FB), «символ медицины» (U+2695) и zero-width joiner (U+200D) между ними. Такая комбинация вообще не декларируется стандартом и эмодзи такого в Unicode нет по понятным причинам.

https://habr.com/company/1c/blog/429678 … t_19366794

Юникод — это фундаментально кодировка с переменной длиной графем. Работать с текстом в основном надо либо на визуальном уровне графем (иногда их частей) для отображения и редактирования, либо на уровне байтов для передачи и хранения. Формат представления никак не помогает правильно работать с графемами: что в UTF-32, что в UTF-8 надо знать отдельные правила их обработки. В любом случае для обработки графем придётся жить с тем, что один условный char в массиве не соответствует одной графеме.

Описание реализации строк в языке Swift (символ - это группа глифов/кодепоинтов, внутреннее представление скрывается от программиста-пользователя языка).

Отредактировано Лис (2019-03-26 18:27:32)

0

11

Итак, при считывании файла в UTF-8 могут возникать ошибки:
- может быть встречен неправильный байт, которого не может существовать по правилам кодирования
- может попастся символ (последовательность модификаторов), который не определён в стандарте Unicode
- может попастся символ, который не может быть преобразован во внутреннюю кодировку компилятора,
например если компилятор ориентируется на кириллицу, а попадётся символ из английского алфавита.

Со всеми этими ошибками нужно как-то бороться. Freeman предлагает сразу барть другую кодировку, но мне кажется, что останавливаться на первой встреченной ошибке неспортивно, нужно иметь стратегию восстановления при ошибках. Кто-нибудь видел подобную?

0

12

Что мешает перечислить необходимые точки из юникода и поддерживать подобные перечисления?
Разве что восьмибитка это слишком много для русского языка.

Отредактировано MihalNik (2019-03-26 19:46:42)

0

13

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

восьмибитка это слишком много для русского языка.

Мало. У нас 33 буквы, это 6 битов. У нас строчные и заглавные (ещё 1 бит). У нас 3 вида ударений (ну или хотя бы один), вот уже 8 бит заполнены.

0

14

У нас 3 вида ударений.

Расстановка ударений может быть исполнена внешней средой - для чтения. Или Лис предлагает набирать каждый раз вручную?

Отредактировано MihalNik (2019-03-26 20:18:25)

0

15

Строки как Double

0

16

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

Расстановка ударений может быть исполнена внешней средой - для чтения

В целом помощь в расстановке ударений - это интересная идея. Но среда не во всех случаях сможет определить, где нужно поставить ударение.
Если бы она была такая умная, то и тексты не надо было бы набирать - она бы писала их сама.

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

Или Лис предлагает набирать каждый раз вручную?

Ну сейчас же набира́ет, если ему хочется?

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

У нас 33 буквы, это 6 битов. У нас строчные и заглавные (ещё 1 бит). У нас 3 вида ударений (ну или хотя бы один), вот уже 8 бит заполнены.

Ударения могут падать только на гласные буквы. А их меньше, чем всех букв. Это должно позволить упаковать три вида ударений в один байт.
10 гласных * 4 варианта (без ударения, и три с ударениями) = 40 букв + 22 согласные, всё ещё помещаемся в 6 бит, заглавность - седьмой бит.
Остаётся ещё место под бит "древние буквы", чтобы передавать дореволюционные буквы и какие там ещё бывают.
Ещё последний бит можно использовать под титло, или без титла, а место отвести под цифры.
(места в кодировке с титлом останется всего на один знак препинания и пробел 64-40-22=2, мало, но зато без иностранных индийских цифр из арабских чисел)
Ударения с титлом не комбинируются вроде бы, поэтому там где-то 30 символов остаётся на знаки препинания (и, так и быть, на цифры)...

В предыдущей теме про кодировку
Ищу кодировку
древние буквы учтены не были...

И кнопку переключения эпохи на клавиатуре можно было бы сделать (по аналогии с Caps Lock или даже на её месте), с двумя положениями:
- современные буквы, осквернённые глобализацией
- церковнославянские, православные

Отредактировано Лис (2021-11-27 08:38:29)

0

17

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

Но среда не во всех случаях сможет определить, где нужно поставить ударение.
Если бы она была такая умная, то и тексты не надо было бы набирать - она бы писала их сама.

Но среда может, например, определить случаи, где она их не сможет проставить по словарю.

0

18

Меня долго мучала необходимость называть UTF-8 буквами латиницы.

УПС-8
    ужасное представление символов 8-ми битными группами битов

такое имя я предлагаю использовать.

Теперь ещё надо придумать название для альтернативной кодировки, которую я предлагал раньше (там где кириллица в символах 0..127 и биты продолжения/стартовые биты определены по-другому)

может быть назвать КРЯ-8 (Кириллическая кодировка Российских Языков), в честь безвременно покинувшего форум Уткина?

Но понадобятся и другие слова, чтобы перекодировать УПС-8 в КРЯ-8.

юникод <-> Unicode
юнипоинт <-> Codepoint
юниграфема <-> Extended Grapheme Cluster (ранее он же был Grapheme Cluster)
юникластер <-> Grapheme Cluster Set (TextElement)

для российской кодировки (как её назвать?) надо подумать

юнипоинт <-> закорючка
юниграфема <-> группаклякс
юникластер <-> символ

КОЗА
    Комплект Обобщенных Закорючек для Алфавита

Не очень удачное название, нужны идеи...

УТКА
    унифицированная таблица кривулин алфавитов

Стандарт УТКА в кодировке КРЯ-8, кто может, пусть называет лучше.

Отредактировано Лис (2022-12-14 18:25:36)

0

19

https://www.opennet.ru/openforum/vsluhf … 4.html#697

2021-12-15, «А ASCII таблицу они под русский переделали? Так что бы все русские символы в первых 7 битах, а латиница уже вариантом кодировки. »

Дыа! Несколько лет назад.

0


Вы здесь » ПО, ЭВМ и АСУ из Таможенного Союза » обработка текста » Строки, хранение и обработка