Если UTF-8 является 8-битной кодировкой, зачем ей нужны 1-4 байта?

на сайте 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 ответов


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

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

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

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

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

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

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


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

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

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

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


UTF-8 является 8-битным переменной ширины кодировка. Первые 128 символов в Юникоде, представленные с кодировкой 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 байт (правый столбец) для разных диапазонов символов в Юникоде (левый столбец).

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