Сколько байтов принимает один символ 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
Хорошо, я увлекся...
Интересные факты:
Ответ 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.
Ответ 6
Существует отличный инструмент для вычисления байтов любой строки в UTF-8: http://mothereff.in/byte-counter
Обновление: @mathias сделал код общедоступным: https://github.com/mathiasbynens/mothereff.in/blob/master/byte-counter/eff.js
Ответ 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.
Вот как я начал понимать кодировки вообще.
Ответ 11
Посмотрите Конвертер кода Unicode. Например, введите 0x2009
, где 2009 - это номер Юникода для тонкого пространства, в поле "0x... нотация" и нажмите "Конвертировать". Шестнадцатеричное число E2 80 89
(3 байта) появляется в поле "Кодовые единицы UTF-8".