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

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

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

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

Я прочитал статью в Википедии о Юникоде, но для меня это довольно сложно. Я с нетерпением жду ответа на простой ответ.

Ответ 1

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

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

Юникод сам по себе является сопоставлением, он определяет кодовые точки, а кодовой точкой является число, связанное обычно с символом. Обычно я говорю, потому что есть такие понятия, как объединение символов. Вы можете быть знакомы с такими вещами, как акценты или умлауты. Они могут использоваться с другим символом, таким как a или u, чтобы создать новый логический символ. Следовательно, символ может состоять из 1 или более кодовых точек.

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

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

Ответ 2

Как ни странно, никто не указал, как рассчитать, сколько байтов принимает один Unicode char. Вот правило для кодированных строк 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 байт, в зависимости от первого, который укажет, сколько байтов оно займет.

Update

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

Ответ 3

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

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

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

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

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

Ответ 4

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

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

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

Сколько байтов требуется символу Unicode?

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

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

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

Итак, сколько байтов требуется для каждого символа?

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

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

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

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

    • 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: E2 80 94
      • UTF-16: 20 14
    • U + 2030 PER MILLE SIGN:
      • Nº: 8240
      • UTF-8: E2 80 B0
      • UTF-16: 20 30
    • U + 20AC EURO SIGN:
      • Nº: 8364
      • UTF-8: E2 82 AC
      • UTF-16: 20 AC
    • U + 2122 ЗНАК ТОРГОВОЙ МАРКИ:
      • Nº: 8482
      • UTF-8: E2 84 A2
      • UTF-16: 21 22
    • U + 2603 SNOWMAN:
      • 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 UMBRELLA С ДОЖДЯМИ:
      • 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 ATOM SYMBOL:
      • Nº: 9883
      • UTF-8: E2 9A 9B
      • UTF-16: 26 9B
    • U + 2708 САМОЛЕТ:
      • Nº: 9992
      • UTF-8: E2 9C 88
      • UTF-16: 27 08
    • U + 271E SHADOWED WHITE LATIN CROSS:
      • Nº: 10014
      • UTF-8: E2 9C 9E
      • UTF-16: 27 1E
    • U + 3020 ПОЧТОВЫЙ МАРК ЛИЦ:
      • Nº: 12320
      • UTF-8: E3 80 A0
      • UTF-16: 30 20
    • U + 8089 CJK UNIFIED IDEOGRAPH-8089:
      • Nº: 32905
      • UTF-8: E8 82 89
      • UTF-16: 80 89
    • U + 1F4A9 PILE OF POO: 💩
      • 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
      • UTF-16: D8 3D DE 80

Хорошо, я увлекся...

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

  • Если вы ищете конкретный символ, вы можете скопировать и вставить его на http://codepoints.net/.
  • Я потратил много времени на этот бесполезный список (но он отсортировался!).
  • MySQL имеет кодировку под названием "utf8", которая на самом деле не поддерживает символы длиной более 3 байтов. Итак, вы не можете вставить кучу poo, поле будет тихо усечено. Вместо этого используйте "utf8mb4".
  • Там страница снеговика (unicodesnowmanforyou.com).

Ответ 5

В Юникоде ответ нелегко дать. Проблема, как вы уже указали, - это кодировки.

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

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

Что делает его настолько трудным, по крайней мере, две вещи:

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

Ответ 7

В 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.

Ответ 8

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

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

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

См. http://unicodebook.readthedocs.io/unicode_encodings.html, раздел 7.5.

Ответ 9

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

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

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

Ответ 10

Я знаю, что это только ссылка, но вы должны посмотреть на это.

http://farmdev.com/talks/unicode/

В нем объясняется, как python обрабатывает unicode, предоставляя четкое и краткое объяснение ASCII и UNICODE.

Вот как я начал понимать кодировки вообще.