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

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

130 голосов
/ 11 января 2011

Разница между 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();

Ответы [ 5 ]

275 голосов
/ 11 января 2011

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

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

Основные плюсы UTF-8:

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

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

  • Многие обычные символы имеют разную длину, что замедляет индексацию по кодам и ужасно вычисляет количество кодов.
  • Даже если порядок байтов не имеет значения, иногда UTF-8 все еще имеет спецификацию (порядок байтов)mark), который служит для уведомления о том, что текст кодируется в 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-совместимость.

18 голосов
/ 11 января 2011

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

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

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

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

См. на этой странице для получения дополнительной информации о UTF-8 и Unicode.

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

4 голосов
/ 11 января 2011

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

static byte[] toBytes(String s){
        byte[] b=new byte[s.length()*2];
        ByteBuffer.wrap(b).asCharBuffer().put(s);
        return b;
    }
0 голосов
/ 30 мая 2019

Безопасность: использовать только UTF-8

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

В реализациях UTF-16 было по крайней мере несколько уязвимостей.Подробнее см. Википедия .

WHATWG и W3C имеют теперь объявлено , что только UTF-8 должно использоваться в Интернете.

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

Другие группы говорят то же самое.

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

0 голосов
/ 27 марта 2016

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

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

...