2012-03-02 2 views
54

Каково максимальное количество байтов для одного кодированного символа UTF-8?Каково максимальное количество байтов для кодированного символа UTF-8?

Я буду шифровать байты строки, закодированной в UTF-8, и, следовательно, должен иметь возможность выработать максимальное количество байтов для кодированной строки UTF-8.

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

+1

Вы * сделали * взгляните на общие ресурсы, такие как [статья UTF-8 Википедии] (http://en.wikipedia.org/wiki/UTF-8), сначала ... правильно? –

+3

Я прочитал несколько статей, которые дали смешанные ответы ... У меня на самом деле сложилось впечатление, что ответ был 3, поэтому я очень рад, что спросил – Edd

+1

. Я оставлю ссылку на youtube здесь, показывая персонажи Тома Скотта, символы, чудо Unicode: https: //goo.gl/sUr1Hf. Вы можете услышать и посмотреть, как все происходит от кодировки символов ASCII до utf-8. – Roylee

ответ

61

Максимальное количество байт на символ является 4 в соответствии с RFC3629, который ограничивал таблицу символов для U+10FFFF:

В UTF-8 символы из диапазона U + 0000..U + 10FFFF (доступный диапазон UTF-16 ) кодируются с использованием последовательностей от 1 до 4 октетов.

(Исходная спецификация допускается до шести байт-кодов символов для кодовых точек прошлых U+10FFFF.)

символов с кодом меньше 128 потребуется 1 байты только, а следующие 1920 кодов символов требуют 2 байтов. Если вы не работаете с эзотерическим языком, умножение количества символов на 4 будет значительной переоценкой.

+2

Что такое "esotheric language"? Любой язык, который будет существовать в реальном мире, или текст, который переключается между разными языками мира? Должен ли разработчик функции UTF-8-to-String выбирать 2, 3 или 4 в качестве мультипликатора, если он выполняет перераспределение и уменьшает результат после фактического преобразования? –

+1

@rinntech по «эзотерическому языку» он означает язык, который имеет много символов unicode с высоким значением (что-то около нижней части этого списка: http://unicode-table.com/en/sections/). Если вам нужно перераспределить, выберите 4. Вы можете сделать двойной проход, один, чтобы увидеть, сколько байтов вам нужно и выделить, а затем другое сделать кодировку; что может быть лучше, чем выделение ~ 4 раза необходимой ОЗУ. – matiu

+4

Всегда старайтесь обрабатывать наихудший случай: http://www.hacker9.com/single-message-can-crash-whatsapp.html –

22

Без дальнейшего контекста, я бы сказал, что максимальное количество байтов для символа в UTF-8 является

Ответ: 6 байт

Автор принятого ответа правильно указал на это как " оригинальная спецификация ", но я думаю, что это вводит в заблуждение читателя, потому что, насколько я знаю, это все еще текущая и правильная спецификация, за wikipedia и за a Google book on UTF-8 in Java.

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

ответ, если перевод только символы из UTF-16 в UTF- 8: 4 байта

Теперь все символы, которые могут быть представлены UTF-16 полезными? Согласно wikipedia again, unicode может представлять до кодовых точек x10FFFF. Таким образом, включая 0, это означает, что мы можем сделать это с помощью этих байтов: F FF FF, то есть два с половиной байта или 20 бит. Оглядываясь на спецификацию UTF-8, мы видим, что мы можем представлять 20 бит с четырьмя байтами с кодировкой UTF-8. Так

ответа, если покрытие всего Юникода: 4 байта

Но, в Java <= v7, они говорят о максимуме в 3 байт для представления Юникода с UTF-8? Это потому, что исходная спецификация Юникода определяла только базовую многоязычную плоскость (BMP), то есть это более ранняя версия юникода или подмножество современного юникода. Так

ответ, если представляющий только оригинальные юникода, ВМР: 3 байта

Но, как О.П. переговоры о переходе в другую сторону. Не от символов до байтов UTF-8, а от байтов UTF-8 до «String» представления байтов. Возможно, автор принятого ответа получил это из контекста вопроса, но это не обязательно очевидно, поэтому может запутать случайного читателя этого вопроса.

Переходя от UTF-8 к собственной кодировке, мы должны посмотреть, как реализована «String». Некоторые языки, такие как Python> = 3, будут представлять каждый символ с целыми кодовыми точками, что позволяет использовать 4 байта на символ = 32 бит, чтобы покрыть 20, которые нам нужны для unicode, с некоторыми отходами. Почему не ровно 20 бит? Потому что вещи быстрее, когда они выровнены по байтам. Некоторые языки, такие как Python < = 2 и Java, представляют символы с использованием кодировки UTF-16, что означает, что они должны использовать суррогатные пары для представления расширенного unicode (а не BMP). В любом случае это максимум 4 байта.

ответ, если собираетесь UTF-8 -> родной кодировки: 4 байта

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

+1

«это все еще текущая и правильная спецификация, по википедии» - больше нет. Вскоре после того, как вы написали это (редактирование 2 апреля), статья Википедии UTF-8 была изменена, чтобы уточнить, что версия с 6 октетами не является частью текущей (2003) спецификации UTF-8. –

+0

«Но, на Java <= v7, они говорят о 3-байтовом максимуме для представления unicode с UTF-8? Это потому, что исходная спецификация Юникода определяла только базовую многоязычную плоскость». Это, вероятно, исходная причина, но это не вся история. Java использует «модифицированный UTF-8», и одна из модификаций заключается в том, что он «использует свой собственный двухкратный трехбайтовый формат» вместо «четырехбайтового формата стандартного UTF-8» (их слова). –

+0

Нет кодовых точек, выделенных над пределом 10FFFF (чуть более миллиона), и многие из реализаций UTF8 никогда не реализовывали последовательности длиной более 4 байтов (и некоторые только 3, например MySQL), поэтому я считаю, что это безопасно с жестким ограничением до 4 байтов на один кодовый пример даже при рассмотрении совместимости со старыми реализациями. Вам просто нужно будет отбросить что-либо недействительное на пути. Обратите внимание, что рекомендация Matiu по распределению после вычисления точной длины байта является хорошей, когда это возможно. – thomasrutter

Смежные вопросы