Если UTF-8 является 8-битной кодировкой, зачем ему 1-4 байта? - PullRequest
8 голосов
/ 14 июня 2011

На сайте Unicode написано, что UTF-8 может быть представлен 1-4 байтами. Как я понял из этого вопроса https://softwareengineering.stackexchange.com/questions/77758/why-are-there-multiple-unicode-encodings UTF-8 - это 8-битная кодировка. Так в чем правда? Если это 8-битное кодирование, то в чем разница между ASCII и UTF-8? Если это не так, то почему он называется UTF-8 и зачем нам UTF-16 и другие, если они занимают одну и ту же память?

Ответы [ 3 ]

16 голосов
/ 14 июня 2011

Абсолютный минимум каждый разработчик программного обеспечения Абсолютно, положительно должен знать о Unicode и наборах символов (без извинений!), Джоэл Спольски - среда, 8 октября 2003 г.

Выдержка сверху:

Так была изобретена блестящая концепция UTF-8. UTF-8 была еще одной системой для хранения вашей строки кодовых точек Unicode, тех магических чисел U +, в памяти, используя 8-битные байты. В UTF-8 каждая кодовая точка от 0 до 127 хранится в одном байте. Только кодовые точки 128 и выше сохраняются с использованием 2, 3, фактически до 6 байтов. Это имеет приятный побочный эффект: английский текст в UTF-8 выглядит точно так же, как и в ASCII, поэтому американцы даже не замечают ничего плохого. Только остальной мир должен прыгать через обручи. В частности, Hello, который был U + 0048 U + 0065 U + 006C U + 006C U + 006F, будет сохранен как 48 65 6C 6C 6F, что, вот! такое же, как и в ASCII, и в ANSI, и в каждом OEM-наборе символов на планете. Теперь, если вы настолько смелы, чтобы использовать буквы с акцентом или греческие буквы или буквы клингона, вам придется использовать несколько байтов для хранения одной кодовой точки, но американцы никогда не заметят. (UTF-8 также обладает хорошим свойством, которое игнорирует старый код обработки строк, который хочет использовать один 0-байт в качестве нулевого терминатора, не будет обрезать строки).

До сих пор я говорил вам о трех способах кодирования Unicode. Традиционные методы store-it-in-двухбайтовые называются UCS-2 (потому что он имеет два байта) или UTF-16 (потому что он имеет 16 бит), и вам все еще нужно выяснить, является ли это UCS 2 или младший байтовый код UCS-2. И есть популярный новый стандарт UTF-8, который обладает прекрасным свойством также работать респектабельно, если у вас есть счастливое совпадение программ на английском языке и программ для мозговых мертвецов, которые совершенно не знают, что есть что-то кроме ASCII.

На самом деле существует множество других способов кодирования Unicode. Есть что-то под названием UTF-7, которое во многом похоже на UTF-8, но гарантирует, что старший бит всегда будет равен нулю, так что если вам придется пропустить Unicode через какую-то драконовскую систему электронной почты полицейского государства, которая думает, что 7 бит вполне достаточно, спасибо, что он все еще может выжать невредимым. Есть UCS-4, в котором каждая кодовая точка хранится в 4 байтах, и у нее есть замечательное свойство, заключающееся в том, что каждая отдельная кодовая точка может храниться в том же количестве байтов, но, черт возьми, даже техасцы не будут настолько смелыми, чтобы тратить их впустую. столько памяти.

И фактически теперь, когда вы думаете о вещах в терминах платонических идеальных букв, которые представлены кодовыми точками Unicode, эти кодовые точки Unicode могут быть закодированы в любой схеме кодирования старой школы! Например, вы можете закодировать строку Unicode для Hello (U + 0048 U + 0065 U + 006C U + 006C U + 006F) в ASCII, или в старой греческой кодировке OEM-производителя, или в кодировке иврита ANSI, или в любой из нескольких сотен кодировок. которые были изобретены до сих пор, с одним уловом: некоторые буквы могут не отображаться! Если нет эквивалента для кодовой точки Unicode, которую вы пытаетесь представить в кодировке, в которой вы пытаетесь ее представить, вы обычно получаете небольшой знак вопроса: или, если ты действительно хорош, коробка. Что вы получили? ->

Существуют сотни традиционных кодировок, которые могут правильно хранить только некоторые кодовые точки и превращать все остальные кодовые точки в вопросительные знаки. Некоторые популярные кодировки английского текста: Windows-1252 (стандарт Windows 9x для западноевропейских языков) и ISO-8859-1, также известный как Latin-1 (также полезный для любого западноевропейского языка). Но попробуйте хранить русские или ивритские буквы в этих кодировках, и вы получите кучу вопросительных знаков. Все UTF 7, 8, 16 и 32 обладают хорошим свойством возможности правильно хранить любую кодовую точку.

12 голосов
/ 14 июня 2011

UTF-8 представляет собой 8-битное кодирование переменной ширины .Первые 128 символов в Unicode, когда они представлены в кодировке UTF-8, имеют представление в виде символов в ASCII.

Чтобы понять это далее, Unicode рассматривает символы как кодовые точки - простое число, которое может быть представлено в несколькихпути (кодировки).UTF-8 является одним из таких кодировок.Это наиболее часто используемый, поскольку он дает лучшие характеристики потребления пространства среди всех кодировок.Если вы сохраняете символы из набора символов ASCII в кодировке UTF-8, то данные в кодировке UTF-8 будут занимать столько же места.Это позволило приложениям, которые ранее использовали ASCII, плавно переходить (ну, не совсем, но это, конечно, не приводило к чему-то вроде Y2K) в Unicode, поскольку представления символов одинаковы.

Я оставлюВот выдержка из RFC 3629 о том, как будет работать кодировка UTF-8:

   Char. number range  |        UTF-8 octet sequence
      (hexadecimal)    |              (binary)
   --------------------+---------------------------------------------
   0000 0000-0000 007F | 0xxxxxxx
   0000 0080-0000 07FF | 110xxxxx 10xxxxxx
   0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
   0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Вы заметите, почему кодирование приведет к тому, что символы будут занимать где-то от 1 до 4 байтов(правый столбец) для различных диапазонов символов в Unicode (левый столбец).

UTF-16, UTF-32, UCS-2 и т. д. будут использовать различные схемы кодирования, где кодовые точки будутпредставлены в виде 16-битных или 32-битных кодов вместо 8-битных кодов, которые выполняет UTF-8.

12 голосов
/ 14 июня 2011

8-битное кодирование означает, что отдельные байты кодирования используют 8 бит. Напротив, чистый ASCII является 7-битной кодировкой, поскольку он имеет только кодовые точки 0-127. Раньше у программного обеспечения были проблемы с 8-битными кодировками; Одной из причин кодирования Base-64 и uuencode было получение двоичных данных через системы электронной почты, которые не обрабатывали 8-битные кодировки. Однако прошло уже десять лет или больше с тех пор, как это перестало быть допустимым в качестве проблемы - программное обеспечение должно было быть 8-битным чистым или способным обрабатывать 8-битные кодировки.

Сам Unicode - это 21-битный набор символов. Для этого есть несколько кодировок:

  • UTF-32, где каждая кодовая точка Unicode хранится в 32-разрядном целом числе
  • UTF-16, где многие кодовые точки Unicode хранятся в одном 16-разрядном целом числе, но некоторым нужны два 16-разрядных целых числа (поэтому для каждой кодовой точки Unicode требуется 2 или 4 байта).
  • UTF-8, где кодовые точки Unicode могут требовать 1, 2, 3 или 4 байта для хранения одной кодовой точки Unicode.

Итак, «UTF-8 может быть представлен 1-4 байтами», вероятно, не самый подходящий способ его формулировки. «Кодовые точки Unicode могут быть представлены 1-4 байтами в UTF-8» было бы более уместным.

...