Если вы хотите поддерживать различные языки для веб-контента, вы должны использовать кодировку, которая охватывает весь диапазон Unicode. Лучший выбор для этой цели - UTF-8. UTF-8 является предпочтительной кодировкой для Интернета; от проекта стандарта HTML5 :
Авторам рекомендуется использовать UTF-8. Проверщики соответствия могут посоветовать авторам не использовать устаревшие кодировки. [RFC3629]
По умолчанию для инструментов разработки следует использовать UTF-8 для вновь создаваемых документов. [RFC3629]
UTF-8 и Windows-1252 - единственные кодировки, которые должны поддерживаться браузерами, а UTF-8 и UTF-16 - единственные кодировки, которые должны поддерживаться синтаксическими анализаторами XML. Таким образом, UTF-8 является единственной распространенной кодировкой, которую требуется поддерживать для всего.
Ниже приведен более расширенный ответ на ответ Лив, чем сам по себе ответ; это описание того, почему UTF-8 предпочтительнее UTF-16 даже для контента CJK.
Для символов в диапазоне ASCII UTF-8 более компактен (1 байт против 2), чем UTF-16. Для символов между диапазоном ASCII и U + 07FF (который включает расширенную латиницу, кириллицу, греческий, арабский и иврит), UTF-8 также использует два байта на символ, так что это стирка. Для символов за пределами Базовой многоязычной плоскости как UTF-8, так и UTF-16 используют 4 байта на символ, так что это промывка.
Единственный диапазон, в котором UTF-16 более эффективен, чем UTF-8, предназначен для символов от U + 07FF до U + FFFF, который включает в себя алфавиты и CJK. Даже для большого количества текста в этом диапазоне UTF-8 оказывается сопоставимым, потому что разметка этого текста (HTML, XML, RTF или что-то еще) находится в диапазоне ASCII, для которого UTF-8 составляет половину размер UTF-16.
Например, если я выбираю случайную веб-страницу на японском языке, домашнюю страницу nhk.or.jp, она кодируется в UTF-8. Если я перекодирую его в UTF-16, он вырастет почти вдвое по сравнению с оригинальным размером:
$ curl -o nhk.html 'http://www.nhk.or.jp/'
$ iconv -f UTF-8 -t UTF-16 nhk.html > nhk.16.html
$ ls -al nhk*
-rw-r--r-- 1 lambda lambda 32416 Mar 13 13:06 nhk.16.html
-rw-r--r-- 1 lambda lambda 18337 Mar 13 13:04 nhk.html
UTF-8 лучше почти во всех отношениях, чем UTF-16. Оба они являются кодировками переменной ширины, и поэтому имеют сложность, которая влечет за собой. В UTF-16, однако, 4-байтовые символы встречаются довольно редко, поэтому гораздо проще делать предположения о фиксированной ширине и заставить все работать, пока вы не столкнетесь с угловым случаем, который вы не уловили. Пример этой путаницы можно увидеть в кодировке CESU-8, которую вы получите, если конвертировать текст UTF-16 в UTF-8, просто кодируя каждую половину суррогатной пары как отдельный символ (используя 6 байтов на символ). три байта для кодирования каждой половины суррогатной пары в UTF-8) вместо декодирования пары в ее кодовую точку и ее кодирования в UTF-8. Эта путаница настолько распространена, что ошибочная кодировка фактически была стандартизирована, так что по крайней мере сломанные программы могут быть созданы для взаимодействия.
UTF-8 намного меньше, чем UTF-16 для подавляющего большинства контента, и если вас беспокоит размер, сжатие текста всегда будет лучше, чем просто выбор другой кодировки. UTF-8 совместим с API-интерфейсами и структурами данных, которые используют нулевую последовательность байтов для представления строк, при условии, что ваши API-интерфейсы и структуры данных либо не заботятся о кодировании, либо уже могут обрабатывать различные кодировки в своих строках (например, как и большинство API-интерфейсов для обработки строк в C и POSIX), UTF-8 может работать просто отлично, не имея совершенно нового набора API и структур данных для широких символов. UTF-16 не определяет порядок байтов, поэтому он заставляет вас решать проблемы с порядком байтов; на самом деле существует три разных связанных кодирования: UTF-16, UTF-16BE и UTF-16LE. UTF-16 может быть либо с прямым порядком байтов, либо с прямым порядком байтов, поэтому для спецификации требуется спецификация. UTF-16BE и LE - это версии с прямым и прямым порядком байтов, без спецификации, поэтому вам нужно использовать внеполосный метод (например, HTTP-заголовок Content-Type), чтобы указать, какой из них вы используете, но вне заголовки полосы печально известны своей ошибкой или отсутствием.
UTF-16 - это, по сути, случайность, произошедшая из-за того, что люди думали, что поначалу будет достаточно 16 бит, чтобы кодировать весь Unicode, и поэтому начали менять свое представление и API для использования широких (16-битных) символов.Когда они поняли, что им потребуется больше символов, они разработали схему использования некоторых зарезервированных символов для кодирования 32-битных значений с использованием двух кодовых единиц, чтобы они могли использовать те же структуры данных для нового кодирования.Это принесло все недостатки кодирования с переменной шириной, такого как UTF-8, без большинства преимуществ.