Сколько байтов занимает один символ Unicode?

Я немного смущен кодировками. Насколько я знаю, старые символы ASCII занимали один байт на символ. Сколько байтов требуется символу Unicode?

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

и что делают UTF-7, UTF-6, UTF-16 и т. д. в смысле? Являются ли они разными версиями Unicode?

прочитал статья в Википедии о Unicode но это довольно сложно для меня. Я с нетерпением жду простого ответа.

10 ответов


вы не увидите простой ответ, потому что его нет.

во-первых, Unicode не содержит "каждый символ из каждого языка", хотя он, конечно, пытается.

Unicode сам по себе является отображением, он определяет кодовые точки, А кодовая точка-это число, связанное с обычно символ. Я говорю обычно, потому что есть такие понятия, как сочетание символов. Вы можете быть знакомы с такими вещами, как акценты, или умляуты. Их можно использовать с другим персонажем, такие как a или u для создания нового логического символа. Поэтому символ может состоять из 1 или более кодов.

чтобы быть полезным в вычислительных системах, нам нужно выбрать представление для этого информацию. Это различные кодировки unicode, такие как utf-8, utf-16le, utf-32 и т. д. Они отличаются в значительной степени размером своих codeunits. UTF-32-это самая простая кодировка, у нее есть codeunit, который составляет 32 бит, что означает, что индивидуальная кодовая точка подходит комфортно в центр. Другие кодировки будут иметь ситуации, когда кодовая точка будет нуждаться в нескольких кодовых единицах, или эта конкретная кодовая точка не может быть представлена в кодировке вообще (это проблема, например, с UCS-2).

из-за гибкости объединения символов даже в пределах заданной кодировки количество байтов на символ может варьироваться в зависимости от символа и формы нормализации. Это протокол для работы с персонажами, которые имеют более чем одно представление (можно сказать "an 'a' with an accent" который является 2 кодовыми точками, одна из которых является комбинирующим символом или "accented 'a'" который является одной кодовой точкой).


Как ни странно, никто не указал, как рассчитать сколько байт занимает один символ Юникода. Вот правило для строк в кодировке UTF-8:

Binary    Hex          Comments
0xxxxxxx  0x00..0x7F   Only byte of a 1-byte character encoding
10xxxxxx  0x80..0xBF   Continuation bytes (1-3 continuation bytes)
110xxxxx  0xC0..0xDF   First byte of a 2-byte character encoding
1110xxxx  0xE0..0xEF   First byte of a 3-byte character encoding
11110xxx  0xF0..0xF4   First byte of a 4-byte character encoding

Итак, быстрый ответ: он занимает от 1 до 4 байт, в зависимости от первого, который укажет, сколько байтов он займет.

обновление

As prewett указал, это правило применяется только к UTF-8


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

насколько я знаю, старые символы ASCII занимали один байт на символ.

право. На самом деле, поскольку ASCII является 7-битной кодировкой, он поддерживает 128 кодов (95 из которых можно распечатать), поэтому он использует только половину байта (если это имеет смысл).

сколько байтов делает Unicode характер требуется?

Unicode просто сопоставляет символы с кодовыми точками. Он не определяет, как их кодировать. Текстовый файл содержит не символы Юникода, а байты/октеты, которые могут представлять символы Юникода.

я полагаю, что один символ Юникода может содержать все возможные характер с любого языка-я прав?

нет. Но почти. Так что в принципе да. Но все равно нет.

Так сколько байты нужны для каждого символа?

то же, что и ваш 2-й вопрос.

и что означает UTF-7, UTF-6, UTF-16 и т. д.? Являются ли они своего рода Unicode версии?

нет, это кодировки. Они определяют, как байты / октеты должны представлять символы Юникода.

пара примеров. Если некоторые из них не могут быть отображены в вашем браузере (возможно, потому, что шрифт их не поддерживает), перейдите в http://codepoints.net/U+1F6AA (заменить 1F6AA С кода в hex), чтобы увидеть изображение.

    • U + 0061 ЛАТИНСКАЯ СТРОЧНАЯ БУКВА A:a
      • Nº: 97
      • UTF-8: 61
      • UTF-16: 00 61
    • U + 00A9 ЗНАК АВТОРСКОГО ПРАВА:©
      • Nº: 169
      • UTF-8: C2 A9
      • UTF-16: 00 A9
    • U+00AE ЗАРЕГИСТРИРОВАННЫЙ ЗНАК: ®
      • Nº: 174
      • UTF-8: C2 AE
      • UTF-16: 00 AE
    • U+1337 ЭФИОПСКИЙ СЛОГ PHWA:
      • Nº: 4919
      • UTF-8: E1 8C B7
      • UTF-16: 13 37
    • U + 2014 EM DASH:
      • Nº: 8212
      • кодировка UTF-8: Е2 80 94
      • UTF-16: 20 14
    • U + 2030 ЗА МИЛЛЕ ЗНАК:
      • Nº: 8240
      • в UTF-8: Е2 80 В0
      • UTF-16: 20 30
    • U + 20AC ЗНАК ЕВРО:
      • Nº: 8364
      • UTF-8: E2 82 AC
      • UTF-16: 20 AC
    • ЗНАК ТОРГОВОЙ МАРКИ U+2122:
      • Nº: 8482
      • в UTF-8: Е2 84 А2
      • UTF-16: 21 22
    • U+2603 СНЕГОВИК:
      • Nº: 9731
      • UTF-8: E2 98 83
      • UTF-16: 26 03
    • U+260E ЧЕРНЫЙ ТЕЛЕФОН:
      • Nº: 9742
      • UTF-8: E2 98 8E
      • UTF-16: 26 0E
    • U+2614 ЗОНТИК С КАПЛЯМИ ДОЖДЯ:
      • Nº: 9748
      • UTF-8: E2 98 94
      • UTF-16: 26 14
    • U + 263A БЕЛОЕ УЛЫБАЮЩЕЕСЯ ЛИЦО:
      • Nº: 9786
      • UTF-8: E2 98 BA
      • UTF-16: 26 3A
    • U + 2691 ЧЕРНЫЙ ФЛАГ:
      • Nº: 9873
      • UTF-8: E2 9A 91
      • UTF-16: 26 91
    • U + 269B СИМВОЛ АТОМА:
      • Nº: 9883
      • UTF-8: E2 9A 9B
      • UTF-16: 26 9Б
    • U+2708 САМОЛЕТ:
      • Nº: 9992
      • UTF-8: E2 9C 88
      • UTF-16: 27 08
    • U+271E ЗАТЕНЕННЫЙ БЕЛЫЙ ЛАТИНСКИЙ КРЕСТ:
      • Nº: 10014
      • UTF-8: E2 9C 9E
      • UTF-16: 27 1E
    • U + 3020 ПОЧТОВЫЙ ЗНАК ЛИЦО:
      • Nº: 12320
      • UTF-8: E3 80 А0
      • UTF-16: 30 20
    • U+8089 CJK УНИФИЦИРОВАННАЯ ИДЕОГРАММА-8089:
      • Nº: 32905
      • UTF-8: E8 82 89
      • UTF-16: 80 89
    • U+1F4A9 КУЧА КАКАШЕК:
      • Nº: 128169
      • UTF-8: F0 9F 92 A9
      • UTF-16: D8 3D DC A9
    • U+1F680 ROCKET:
      • Nº: 128640
      • UTF-8: F0 9F 9A 80
      • УТФ-16: Д8 3Д-де-80

ОК Я увлекся...

интересные факты:


проще говоря Unicode - это стандарт, который присвоил один номер (называемый кодовой точкой) всем символам мира (его работа все еще продолжается).

теперь вам нужно представить эти кодовые точки с помощью байтов, которые называются character encoding. UTF-8, UTF-16, UTF-6 способы представления этих символов.

UTF-8 - это многобайтовая кодировка. Символы могут иметь от 1 до 6 байт (некоторые из них могут не потребоваться прямо сейчас).

UTF-32 каждый символ имеет 4 байта характер.

UTF-16 использует 16 бит для каждого символа и представляет только часть символов Юникода, называемых BMP (для всех практических целей его достаточно). Java использует эту кодировку в своих строках.


в Unicode ответ дается нелегко. Проблема, как вы уже отметили, заключается в кодировках.

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

единственная кодировка, в которой (на данный момент) мы можем сделать заявление о размере,-UTF-32. Там всегда 32bit на символ, хотя я предполагаю, что кодовые точки подготовлен к будущему UTF-64:)

что делает это так сложно, по крайней мере две вещи:

  1. составленные символы, где вместо использования сущности символа, который уже акцентирован / диакритический (À), пользователь решил объединить акцент и базовый символ (`A).
  2. кодовые точки. Кодовые точки-это метод, с помощью которого UTF-кодировки позволяют кодировать больше, чем обычно позволяет количество битов, которое дает им их имя. Е. Г. В UTF-8 обозначает определенные байты, которые сами по себе являются недопустимыми, но при последующем действительном продолжении байт позволит описать символ за пределами 8-битного диапазона 0..255. Вижу примеры и Overlong кодировки ниже в статье Википедии на UTF-8.
    • отличным примером, приведенным там, является то, что символ € (кодовая точка U+20AC может быть представлена как три-байт последовательность E2 82 AC или четыре-байт последовательность F0 82 82 AC.
    • оба действительны, и это показывает, насколько сложным является ответ, когда речь идет о "Unicode", а не о конкретной кодировке Unicode, такой как UTF-8 или UTF-16.

в UTF-8:

1 byte:       0 -     7F     (ASCII)
2 bytes:     80 -    7FF     (all European plus some Middle Eastern)
3 bytes:    800 -   FFFF     (multilingual plane incl. the top 1792 and private-use)
4 bytes:  10000 - 10FFFF

в UTF-16:

2 bytes:      0 -   D7FF     (multilingual plane except the top 1792 and private-use )
4 bytes:   D800 - 10FFFF

в UTF-32:

4 bytes:      0 - 10FFFF

10FFFF-последняя кодовая точка unicode по определению, и она определена таким образом, потому что это Технический предел UTF-16.

Это также самая большая кодовая точка UTF-8 может кодироваться в 4 байта, но идея кодирования UTF-8 также работает для 5 и 6 байтовых кодировок для покрытия кодовых точек до 7FFFFFFF, т. е. половина того, что может UTF-32.


существует отличный инструмент для вычисления байтов любой строки в UTF-8:http://mothereff.in/byte-counter

Update: @mathias опубликовал код: https://github.com/mathiasbynens/mothereff.in/blob/master/byte-counter/eff.js


Ну, я просто вытащил страницу Википедии на ней тоже, и в вступительной части я увидел, что "Unicode может быть реализован различными кодировками символов. Наиболее часто используемых кодировок: UTF-8 (который использует один байт за любые ASCII символы, которые имеют одинаковые значения кодов в кодировке UTF-8 и ASCII кодировки, и до четырех байтов для других персонажей), ныне устаревшей кодировке UCS-2 (который использует два байта для каждого символа, но не может кодировать каждый символ в текущей кодировке Unicode стандарт)"

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

таким образом, ваш простой ответ, который вы хотите, заключается в том, что он меняется.


для UTF-16 символу требуется четыре байта (две единицы кода), если он начинается с 0xD800 или больше; такой символ называется "суррогатной парой"."Более конкретно, суррогатная пара имеет вид:

[0xD800 - 0xDBFF]  [0xDC00 - 0xDFF]

где [...] указывает двухбайтовую кодовую единицу с заданным диапазоном. Anything = 0xE000 недопустимо (кроме маркеров спецификации, возможно).

посмотреть http://unicodebook.readthedocs.io/unicode_encodings.html, раздел 7.5.


зацените конвертер кодов Юникода. Например, введите 0x2009, где 2009-Это номер Unicode для тонкого пространства, в " 0x... поле "нотация" и нажмите кнопку Преобразовать. Шестнадцатеричное число E2 80 89 (3 байта) отображается в поле "кодовые единицы UTF-8".