Подтвердить что ты не робот

Разница между UTF-8 и UTF-16?

Разница между UTF-8 и UTF-16? Зачем они нужны?

MessageDigest md = MessageDigest.getInstance("SHA-256");
String text = "This is some text";

md.update(text.getBytes("UTF-8")); // Change this to "UTF-16" if needed
byte[] digest = md.digest();
4b9b3361

Ответ 1

Я считаю, что в Интернете есть много хороших статей об этом, но вот краткое резюме.

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

Основные профили UTF-8:

  • Основные символы ASCII, такие как цифры, латинские символы без акцентов и т.д., занимают один байт, который идентичен представлению US-ASCII. Таким образом, все строки US-ASCII становятся действительными UTF-8, что во многих случаях обеспечивает достойную обратную совместимость.
  • Нет нулевых байтов, что позволяет использовать строки с нулевым символом, это также обеспечивает большую обратную совместимость.
  • UTF-8 не зависит от порядка байтов, поэтому вам не нужно беспокоиться о проблеме Big Endian/Little Endian.

Основные UTF-8 минусы:

  • Многие общие символы имеют разную длину, что замедляет индексирование по кодовым точкам и вычисляет число кодов, которое ужасно.
  • Несмотря на то, что порядок байтов не имеет значения, иногда UTF-8 по-прежнему имеет спецификацию (байтовый порядок), который служит для уведомления о том, что текст закодирован в UTF-8, а также нарушает совместимость с программным обеспечением ASCII, даже если только текст содержит символы ASCII. Программное обеспечение Microsoft (например, Блокнот) особенно любит добавлять спецификацию в UTF-8.

Основные профили UTF-16:

  • BMP (базовые многоязычные плоскости), включая латынь, кириллицу, большинство китайцев (КНР поддерживала некоторые кодировки вне BMP), большинство японцев могут быть представлены 2 байтами. Это ускоряет индексирование и вычисление количества кодовых точек в случае, если текст не содержит дополнительных символов.
  • Даже если текст имеет дополнительные символы, они все еще представлены парами 16-битных значений, что означает, что общая длина по-прежнему делится на два и позволяет использовать 16-разрядный char в качестве примитивного компонента строка.

Основные UTF-16 минусы:

  • Множество нулевых байтов в строках US-ASCII, что означает отсутствие нулевых строк и много потерянной памяти.
  • Использование в качестве кодировки фиксированной длины "в основном работает" во многих распространенных сценариях (особенно в США/ЕС/странах с кириллическими алфавитами/Израилем/арабскими странами/Ираном и многими другими), что часто приводит к нарушенной поддержке там, где это происходит "т. Это означает, что программисты должны знать суррогатные пары и правильно обращаться с ними в тех случаях, когда это важно!
  • Это переменная длина, поэтому подсчет или индексирование кодовых точек является дорогостоящим, хотя и меньшим, чем UTF-8.

В общем, UTF-16 обычно лучше подходит для представления в памяти, потому что BE/LE здесь не имеет значения (просто используйте собственный порядок), а индексация выполняется быстрее (просто не забудьте правильно обрабатывать суррогатные пары). UTF-8, с другой стороны, очень хорош для текстовых файлов и сетевых протоколов, потому что нет проблемы с BE/LE, и нулевое завершение часто пригодится, а также совместимость с ASCII.

Ответ 2

Это просто разные схемы для представления символов Unicode.

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

UTF-8 использует от 1 до 3 байтов для символов в BMP, до 4 для символов в текущем Unicode диапазоне от U + 0000 до U + 1FFFFF, и расширяется до U + 7FFFFFFF, если это когда-либо понадобится... но особенно все символы ASCII представлены в каждом байте каждый.

Для целей дайджеста сообщения не имеет значения, какой из них вы выбираете, если все, кто пытается воссоздать дайджест, используют ту же опцию.

Подробнее о UTF-8 и Юникоде см. эту страницу.

(Обратите внимание, что все символы Java являются кодовыми точками UTF-16 в BMP; для представления символов выше U + FFFF вам нужно использовать суррогатные пары в Java.)

Ответ 3

Это не связано с UTF-8/16 (в общем, хотя оно и конвертируется в UTF16, а часть BE/LE может быть установлена ​​с одной строкой), но ниже это самый быстрый способ преобразования String в байт [ ]. Например: хорошо точно для предоставленного случая (хэш-код). String.getBytes(enc) относительно медленный.

static byte[] toBytes(String s){
        byte[] b=new byte[s.length()*2];
        ByteBuffer.wrap(b).asCharBuffer().put(s);
        return b;
    }

Ответ 4

Простой способ дифференцировать UTF-8 и UTF-16 - идентифицировать общие черты между ними.

Помимо совместного использования одного и того же номера юникода для заданного символа, каждый из них является их собственным форматом.