Будущее за UTF-8?

 
1 2 3 4
+
-
edit
 

Mishka

модератор
★★★

Dmitry_A>>Роман, не переживай, Юникода на всех хватит ;) .[»]
Balancer>В виде UTF-8 - да. А классический двухбайтовый Юникод - уже сейчас не хватает :) Т.е. в UTF-8 есть куча групп символов, которые в Unicode просто не влезли.[»]

Ром, ты не прав. UTF-8 - это один из способов машинного представления Unicode. Есть еще и UTF-16, UTF-32 - http://www.unicode.org/versions/Unicode4.0.0/ch02.pdf - 2.5 и 2.6 смотреть - (не говоря о других) - просто в двух последних . А двухбайтовый классический Unicode - это старая версия. Новая (Unicode Consortium) уже включает больше несколько лет. Просто мелко-мягкий не поспевает. А скажем, тот же Solaris, HP-UX, вроде и Линь давно уже поддерживают wchar в 4 байта.

И последнее в этом оффе - кому интересно как это для программистов - вот неплохой обзор - UTF-8 and Unicode FAQ.
 
+
-
edit
 

Balancer

администратор
★★★★★
Миш, ты не совсем прав :D Уже сейчас по стандарту UTF-8 кодирует 231 символов и в рамках же стандарта расширается до произвольного числа символов. Его аналог, классический тридцатидвухбитный Unicode, крайне неудобен по всем параметрам, начиная от его обработки, кончая тем, что отводить по 4 байта на каждый символ - это издевательство :)

А всякие wchar в 4 байта - это извращение. В наше время char есть char, и ни о какой его "длине" программист знать не должен :)
 
+
-
edit
 

Mishka

модератор
★★★

Balancer>Миш, ты не совсем прав :D Уже сейчас по стандарту UTF-8 кодирует 231 символов и в рамках же стандарта расширается до произвольного числа символов. Его аналог, классический тридцатидвухбитный Unicode, крайне неудобен по всем параметрам, начиная от его обработки, кончая тем, что отводить по 4 байта на каждый символ - это издевательство :)

Ром, а по какому стандарту UTF-8 кодирует 231 символов? RFC 3629 показывает 21 битик и ссылается на ту книжку, что я привел - там тоже только 21 битик. Кроме того, UTF-8 не имеет бесконечно расширяемости. Одно из свойств UTF-8 - это то, что в потоке байте легко отличить байт данных от байта управления, а байт управления указывает на длину всей кодовой последовательности. А там битиков ограниченное количество.


UTF - любая - это encoding form. UTF + что-то еще - схема. Т.е. это способ представления абстрактного числа, закрепленного за кодовой точкой (собственно символа) в потоке или машине. Это разные вещи. Как имплементация - да есть всякие представления - 32 двух битовые или 16 битовые. Кроме того, Unicode - это не только кодирование, а много чего еще другого. :)

А про 4 байта под каждый символ - это пока с простыми текстами работаешь - а как пойдешь со сложными, так и в UTF-8 будут все многобайтовые.

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

2.4 Code Points and Characters

On a computer, abstract characters are encoded internally as numbers. To create a complete character encoding, it is necessary to define the list of all characters to be encoded and to establish systematic rules for how the numbers represent the characters.

The range of integers used to code the abstract characters is called the codespace. A particular integer in this set is called a code point. When an abstract character is mapped or assigned to a particular code point in the codespace, it is then referred to as an encoded character.

In the Unicode Standard, the codespace consists of the integers from 0 to 10FFFF16, comprising 1,114,112 code points available for assigning the repertoire of abstract characters. Of course, there are constraints on how the codespace is organized, and particular areas of the codespace have been set aside for encoding of certain kinds of abstract characters or for other uses in the standard. For more on the allocation of the Unicode codespace, see Section 2.8, Unicode Allocation.
 


2.5 Encoding Forms

Computers handle numbers not simply as abstract mathematical objects, but as combinations of fixed-size units like bytes and 32-bit words. A character encoding model must take this fact into account when determining how to associate numbers with the characters. Actual implementations in computer systems represent integers in specific code units of particular size—usually 8-bit (= byte), 16-bit, or 32-bit. In the Unicode character encoding model, precisely defined encoding forms specify how each integer (code point) for a Unicode character is to be expressed as a sequence of one or more code units. The Unicode Standard provides three distinct encoding forms for Unicode characters, using 8-bit, 16-bit, and 32-bit units. These are correspondingly named UTF-8, UTF-16, and UTF-32. (The “UTF” is a carryover from earlier terminology meaning Unicode (or UCS) Transformation Format.) Each of these three encoding forms is an equally legitimate mechanism for representing Unicode characters; each has advantages in different environments.

All three encoding forms can be used to represent the full range of encoded characters in the Unicode Standard; they are thus fully interoperable for implementations that may choose different encoding forms for various reasons. Each of the three Unicode encoding forms can be efficiently transformed into either of the other two without any loss of data.
 


2.6 Encoding Schemes
The discussion of Unicode encoding forms in the previous section was concerned with the machine representation of Unicode code units. Each code unit is represented in a computer simply as a numeric data type; just as for other numeric types, the exact way the bits are laid out internally is irrelevant to most processing. However, interchange of textual data, particularly between computers of different architectural types, requires consideration of the exact ordering of the bits and bytes involved in numeric representation. Integral data, including character data, is serialized for open interchange into well-defined sequences of bytes. This process of byte serialization allows all applications to correctly interpret exchanged data and to accurately reconstruct numeric values (and thereby character values) from it. In the Unicode Standard, the specifications of the distinct types of byte serializations
to be used with Unicode data are known as Unicode encoding schemes.


Modern computer architectures differ in ordering in terms of whether the most significant byte or the least significant byte of a large numeric data type comes first in internal representation. These sequences are known as “big-endian” and “little-endian” orders, respectively. For the Unicode 16- and 32-bit encoding forms (UTF-16 and UTF-32), the specification of a byte serialization must take into account the big-endian or little-endian architecture of the system on which the data is represented, so that when the data is byteserialized for interchange it will be well defined.

A character encoding scheme consists of a specified character encoding form plus a specification of how the code units are serialized into bytes. The Unicode Standard also specifies the use of an initial byte order mark (BOM) to explicitly differentiate big-endian or littleendian data in some of the Unicode encoding schemes. (See the “Byte Order Mark” subsection in Section 15.9, Specials.)
 



Balancer>А всякие wchar в 4 байта - это извращение. В наше время char есть char, и ни о какой его "длине" программист знать не должен :)[»]


Вот именно поэтому и не надо вообще про длину говорить. Это абстрактное число - без размера.
 
+
-
edit
 

Balancer

администратор
★★★★★
Mishka>Ром, а по какому стандарту UTF-8 кодирует 231 символов? RFC 3629 показывает 21 битик и ссылается на ту книжку, что я привел - там тоже только 21 битик.

По твоей ссылке с Unicode Faq:
UTF-8 has the following properties:
  • ...
  • All possible 231 UCS codes can be encoded.


Там же ниже примеры соответствующих кодов.
Скажем, 7FFFFFFF будет представлен как FD BF BF BF BF BF

Mishka>Кроме того, UTF-8 не имеет бесконечно расширяемости.

На счёт того, что в рамках стандарта - да, попутал. Но расширяться всё равно может легко. Достаточно зарезервировать ту или иную из более коротких комбинаций (просто уверен, что задействованы они не все) как управляющие. Это лишь немного усложнит анализ, но к тому времени, когда будут исчерпаны 231 символов, думаю, это будет уже совершенно неважно :)

Mishka>А про 4 байта под каждый символ - это пока с простыми текстами работаешь - а как пойдешь со сложными, так и в UTF-8 будут все многобайтовые.

Согласись, что английский текст - это основа любых современных протоколов, начиная от HTTP, кончая XML. И если на основную часть текста придётся тратить по 1 байту вместо четырёх - то это уже огромный плюс :D

Впрочем, как бы ты ни был несогласен, но именно UTF-8 основа всех современных протоколов, начиная от URI, кончая XMPP или XML :)
 
+
-
edit
 

Mishka

модератор
★★★

Mishka>>Ром, а по какому стандарту UTF-8 кодирует 231 символов? RFC 3629 показывает 21 битик и ссылается на ту книжку, что я привел - там тоже только 21 битик.

Я про то, что по стандарту только 21 :P

Balancer>По твоей ссылке с Unicode Faq:
Balancer>UTF-8 has the following properties:
Balancer>* ...
Balancer>* All possible 231 UCS codes can be encoded.
Balancer>Там же ниже примеры соответствующих кодов.
Balancer>Скажем, 7FFFFFFF будет представлен как FD BF BF BF BF BF

Еще один байтик можно добавить и усе - больше не расширишь...

Mishka>>Кроме того, UTF-8 не имеет бесконечно расширяемости.
Balancer>На счёт того, что в рамках стандарта - да, попутал. Но расширяться всё равно может легко. Достаточно зарезервировать ту или иную из более коротких комбинаций (просто уверен, что задействованы они не все) как управляющие. Это лишь немного усложнит анализ, но к тому времени, когда будут исчерпаны 231 символов, думаю, это будет уже совершенно неважно :)

Не, с соблюдением его принципов - никак - один из них - если произошел сбой в потоке, то можно легко промотать не более 6 байт и продолжать. Все таки сетевики здесь поучаствовали.


Balancer>Согласись, что английский текст - это основа любых современных протоколов, начиная от HTTP, кончая XML. И если на основную часть текста придётся тратить по 1 байту вместо четырёх - то это уже огромный плюс :D

Уже не соглашусь. Вот мы на работе, например, начали всемерную поддержку NLS - азиатские рынки просто офигенные. Да и русский контент растет не по дням, а по часам. Немецкого, франузкого, испанского - дохрена. Хотя английского все еще больше. А в XML - вводи тэги любые - там только база английская.

Balancer>Впрочем, как бы ты ни был несогласен, но именно UTF-8 основа всех современных протоколов, начиная от URI, кончая XMPP или XML :)[»]

А здесь я и не спорю :) - я же сразу сказал, что эта форма кодировки - IETF выбрало одну, возвело ее в свой стандарт и вот мы имеем то, что имеем. :D

Но минусы все же есть. Например, многие составные символы - легкая морока. Определение длины строки - та же проблема, что в С. Представление в базе - как резервировать поля? Приходиться давать в 6 раз больше места. Много чего еще есть...
 
+
-
edit
 

Balancer

администратор
★★★★★
Mishka>Я про то, что по стандарту только 21 :P

1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - это 21 битик или же (5*6)+1 = 31? :)

Mishka>Не, с соблюдением его принципов - никак - один из них - если произошел сбой в потоке, то можно легко промотать не более 6 байт и продолжать. Все таки сетевики здесь поучаствовали.

Ладно, уговорил. 231 байт и дальше расширять нельзя. Ну очень мало, по сравнению с 216 "классического" Unicode :)

Mishka>Уже не соглашусь. Вот мы на работе, например, начали всемерную поддержку NLS - азиатские рынки просто офигенные. Да и русский контент растет не по дням, а по часам. Немецкого, франузкого, испанского - дохрена.

Вот только те же XML-тэги всё равно на ангийском пишутся. А не на русском или испанском :)

>А в XML - вводи тэги любые - там только база английская.

Однако, это вполне себе моветон до сих пор. И долго так ещё и будет. Особенно - в синтетических языках.

Mishka>Но минусы все же есть. Например, многие составные символы - легкая морока.

>

>Определение длины строки - та же проблема, что в С.

Кто тебе запрещает хранить со строкой и счётчик?

>Представление в базе - как резервировать поля?

Так же, как и под обычные строки. У них также переменная длина :)

>Приходиться давать в 6 раз больше места.

Ну, в MySQL после перехода на VARCHAR в UTF-8 размеры русских баз увеличились в полтора раза, а не в 6 :)
 
+
-
edit
 

Mishka

модератор
★★★

Хорошо тебе - в 1.5 раза для русского. А мы вон сейчас идем на классический китайский язык :( - т.е. не сами переводим, но должжны рассчитывать на их длину. И где раньше было 255 символов для имен сетевых объектов, сейчас надо в 6 раз больше.
 
+
-
edit
 

Balancer

администратор
★★★★★
Mishka>Хорошо тебе - в 1.5 раза для русского. А мы вон сейчас идем на классический китайский язык :( - т.е. не сами переводим, но должжны рассчитывать на их длину. И где раньше было 255 символов для имен сетевых объектов, сейчас надо в 6 раз больше.[»]

С китайским мне тоже работать приходится, правда, там, где объёмы не критичны - в вёрстке. Только у нас традиционное китайское письмо занимает по три байта. Ну, от балды - 々(E3 80 85) 搏 (E6 90 8F) 蔔 (E8 94 94). Впрочем, даже если бы занимало по 6 байт - всё равно это всего в тех же полтора раза больше, чем 32-битная кодировка :)
 
+
-
edit
 

Balancer

администратор
★★★★★
Чисто для статистики. После конвертации mysql-БД форумов с utf8 на utf8mb4 размер базы вырос с 6896Мб до 7484 Мб. Прирост 8.5%.
 43.0.2357.13443.0.2357.134
+
-
edit
 

Mishka

модератор
★★★

Balancer> Чисто для статистики. После конвертации mysql-БД форумов с utf8 на utf8mb4 размер базы вырос с 6896Мб до 7484 Мб. Прирост 8.5%.

Всё-таки разработчики мускуля те ещё ребята. :F

RFC 2279 - UTF-8, a transformation format of ISO 10646 — оригинальный стандарт (от IETF для интернета, хотя UTF-8 явился миру на конференции USENET, которая проходила 25-29 января 1993), разрешает CODE POINTs, выражаемые числом размерностью до 31 бита (все 6 байтов нужны). Юникодники решили, что больше миллиона этих самых пойнтс не будет (ну может чуток больше), поэтому ограничили только 4 байтами — RFC 3629 - UTF-8, a transformation format of ISO 10646. Если посмотреть на года, то это 1998 и 2003. У мускуля utf8mb4 появился, вроде, только в 5.5. Вопрос, вот нафига они вводили вооще UTF-8, как 3 байтный, когде уже был стандарт на 4-х байтный. А потом ещё и переделывали?
 37.037.0
+
-
edit
 

digger

аксакал

Дилетантская идея.Хранить данные в базе данных в RTF или другом похожем формате ,работающем на переключении кодировок,можно самопальном.Перекодировать в Юникод при генерации страниц.Профит - до 50% объема,если перекодировка на клиенте - то и столько же трафика.Форматы переменной длины или с большим размером буквы более устойчивы к повреждениям,потому их предпочитают форматам с переключением,но тут это менее релевантно.
 44.0.2403.10744.0.2403.107
+
-
edit
 

Balancer

администратор
★★★★★
digger> Перекодировать в Юникод при генерации страниц.Профит - до 50% объема

Экономия на спичках. Во-первых, профит не 50% а заметно меньше (вся латиница/теги, пробелы, знаки препинания — всё однобайтовое) чисто по тексту. Во-вторых, только в базе сообщений текст занимает не львиную долю объёма. В базе сейчас около 1.9 млрд. символов, при худшем раскладе — это под 3.5Гб. А реально все таблицы сообщений весят 15Гб. Почти половину занимают индексы. Остальное — вспомогательные поля (id сообщений, топиков, авторов, аттачей, даты, IP, геоинфо и т.п.) Так что — реально на спичках :)

digger> Форматы переменной длины или с большим размером буквы более устойчивы к повреждениям,потому их предпочитают форматам с переключением

Не поэтому. utf-8 утвердился как совместимый при передаче с однобайтовыми кодировками. Ну и реально по объёму, всё же, сильно экономнее, чем четырёхбайтовые кодировки в условиях доминирования ascii (т.е. весь web).
 43.0.2357.13443.0.2357.134
+
-
edit
 

digger

аксакал

А где-то используется 4-х байтовая кодировка постоянной длины на символ?
 44.0.2403.10744.0.2403.107
+
-
edit
 

Balancer

администратор
★★★★★
digger> А где-то используется 4-х байтовая кодировка постоянной длины на символ?

UTF-32 :)
 43.0.2357.13443.0.2357.134
+
-
edit
 

digger

аксакал

Что с Юниксом? Есть ли ядра, использующие API с UTF-32? T.e. откомпилировать можно,но используется ли где-то реально?
 44.0.2403.10744.0.2403.107
+
-
edit
 

Balancer

администратор
★★★★★
digger> Что с Юниксом? Есть ли ядра, использующие API с UTF-32? T.e. откомпилировать можно,но используется ли где-то реально?

А смысл? Эта кодировка практически нигде не прижилась, скорее как гипотетическая возможность...

UTF-8 реально достаточно универсальна, чтобы её хватило и нам, и нашим детям/правнукам.
 43.0.2357.13443.0.2357.134
+
-
edit
 

digger

аксакал

Просто интересно.В мертвом Питоне-3 же используется. Любой кодировки хватит навсегда : она по определению кодирует все 32 бита кодом переменной длины.Смысл в 32-битной кодировке - постоянная длина,некоторое упрощение вычисления позиции буквы и длины строки.При передаче лишние нули все равно сжимаются зипом,а на компьютере память для строк - не дeфицит.Геи из Майкрософта приняли UTF-16 из великого ума,поначалу как 16-битный фиксированной длины USC-2,не подумав про китайцев, utf-8 был бы лучше.
 44.0.2403.10744.0.2403.107
+
-
edit
 

Balancer

администратор
★★★★★
digger> Смысл в 32-битной кодировке - постоянная длина

Случаи, когда это оправдывает четырёхкратный рост потребления памяти, всё же, редки :)

digger> некоторое упрощение вычисления позиции буквы и длины строки

Только позиция буквы. Длину строки в нормальных языках не считают, а хранят :)

digger> При передаче лишние нули все равно сжимаются зипом

UTF-8 всё равно сожмётся лучше :) Вот взять этот текст — 1063 байт в utf8. 2556 байт в utf32. После сжатия — 571 байт для utf8 и 665 байт для utf32 :)

digger> а на компьютере память для строк - не дeфицит.

Если речь о 1к vs 4к — то да. Если об 1Гб vs 4Гб — то разница уже заметная.
 43.0.2357.13443.0.2357.134

Mishka

модератор
★★★

digger> Что с Юниксом? Есть ли ядра, использующие API с UTF-32? T.e. откомпилировать можно,но используется ли где-то реально?
Посмотри определение wchar_t — сейчас он 32 бита (и довольно давно). Т.е. внутреннее представление UTF-32/UCS-32. Ну и UNICODE достаточно давно уже имеет миллион code points, так что UTF-16/UCS-16 не подходходит (как схема кодирования — подходит, а вот, как представитель UNICODE — нет — смотри мои объяснения про разницу в этой теме).

Вот тут специально расписывал разницу — Кто что делает, компьютерный вариант [часть 3] [Mishka#12.01.09 05:41]
Вообщем, 32 битное представление code point — это encoding form — представление числа, которым закодирован символ, в памяти. Запись/чтение на/с внешней/го носитель/я, передача/приём данных по сети использует encoding scheme. Тут уже появляется те самые Big Endian/Little Endian маркеры и прочее для многобайтных схем.

UTF-8 хорош тем, что:
1. Нет 0 в потоке байтов — схема кодирования это обеспечивает.
2. В случае сбоя легко восстановить остаток, пропустив все байты, которые начинаются с 0x10zzzzzz.
3. На данный момент по текущим стандартам (максимальная длина может быть только 4) занимает не больше памяти, чем UTF-32/UCS-32.

А плох тем, что:
1. Длина в памяти, длина в символах, длина в знакоместах на экране есть три разные величины, и получить просто из одной другую — не выходит. Впрочем, длина в знакоместах всегда сложное дело независимо от кодировки.
2. Достаточно сложно искать в строках с UTF-8 кодированием.
 37.037.0
Это сообщение редактировалось 27.07.2015 в 17:09

digger

аксакал

Mishka> Посмотри определение wchar_t — сейчас он 32 бита (и довольно давно). Т.е. внутреннее представление UTF-32/UCS-32.

На какой платформе? На Виндовс - 16 бит было,есть и будет, это завязано на API.

>Достаточно сложно искать в строках с UTF-8 кодированием.

Oсобенно задом наперед.Или есть хороший алгоритм парсинга предыдущей буквы?
 44.0.2403.10744.0.2403.107

Mishka

модератор
★★★

digger> На какой платформе? На Виндовс - 16 бит было,есть и будет, это завязано на API.

Ы? Это не твоё?

digger> Что с Юниксом?

digger> Oсобенно задом наперед.Или есть хороший алгоритм парсинга предыдущей буквы?
Конечно, всё что начинается с 0x10zzzzzz — продолжение. Иное — начало символа.
 37.037.0

Mishka

модератор
★★★

digger> На какой платформе? На Виндовс - 16 бит было,есть и будет, это завязано на API.

Да, кстати, C++ стандарт требует, чтобы wchar_t вмещал любой символ charset-а. Т.е. винды в лице VC это не далеют, чем автоматом заваливают тест на поддержку unicode по стандарту. Чтобы этого избежать, VC используюте WCHAR, а не wchar_t. Ну и определение wchar_t — это область компилятора, а не ОС.
 37.037.0

digger

аксакал

Держать 3 вида букв : char,wchar для WinAPI и wchar ,вмещающий любой символ в 1 переменной- это слишком.Кроме того,есть такая проблема как составные буквы,где диакритика идет перед/после основной буквой,иногда не одна,и в Юникоде тоже,поэтому не гарантируется ,что длина строки равна длине изображения на экране в буквах.Это делает затею с UTF-32 бессмысленной.В особенности если об этом забыть и потом нарваться на эксплоит. ANSI надо было сразу вводить функцию для парсинга следующей буквы и вычисления длины строки в буквах.
 44.0.2403.10744.0.2403.107

Mishka

модератор
★★★

digger> Держать 3 вида букв : char,wchar для WinAPI и wchar ,вмещающий любой символ в 1 переменной- это слишком.

Как только ты осознаешь зачем были введены charsets, code points, enchoding forms, encoding schemes, так сразу станет легче. :F

digger> Кроме того,есть такая проблема как составные буквы,где диакритика идет перед/после основной буквой,иногда не одна,и в Юникоде тоже,поэтому не гарантируется ,что длина строки равна длине изображения на экране в буквах.

Опять-таки, посмотри на понятие глифа. И это очень старое понятие, ещё у Кнута в его TeX-е было. Пришло оно из печатного дела, поэтому я и упомянул три разные длины. Опять-таки, это отношения к кодированию не имеет. Даже в ASCII у тебя есть куча символов, которые изменяют отображение (новая строка, перевод каретки, горизонтальная и вертикальная табуляции, backspace, etc) и делают текст по длине не равным его изображению. Т.е. проблема известна давно.

digger> Это делает затею с UTF-32 бессмысленной.В особенности если об этом забыть и потом нарваться на эксплоит. ANSI надо было сразу вводить функцию для парсинга следующей буквы и вычисления длины строки в буквах.

Это не делают идею с UTF-32 бесмысленной, т.к. оперировать с массивом элементов фиксированной длины намного проще.
 37.037.0

digger

аксакал

Он - не фиксированной длины.Изменение 1-й логической буквы "и" на "й" может повлечь вставку или убирание элементов из массива.Или найти в строке паттерн "http://ху\wня\.com" ,вначале для производительности расчитав, не длиннее ли строка,чем паттерн,тоже не вычисляется как strlen,разницы в удобстве между UTF-8 и UTF-32 нет.
 44.0.2403.10744.0.2403.107
1 2 3 4

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru