Так что я теперь запутался, что использовать сейчас UTF-8 / UTF-16 / UTF-32 / UCS-2
, что лучше для многоязычного контента и производительности и т. Д.
UCS-2 устарел: он больше не может представлять каждый символ Юникода.UTF-8, UTF-16 и UTF-32 могут все.Но почему есть три разных способа кодирования одних и тех же символов?
Потому что в старые времена программисты делали два больших предположения о строках.
- То, что строки состоят из 8-битных единиц кода.
- Этот 1 символ = 1 единица кода.
Проблема для многоязычного текста (или даже для одноязычного текста, если этот язык оказался китайским, японским или корейским), заключается в том, чтоэти два допущения в совокупности ограничивают вас до 256 символов.Если вам нужно представить более, чем это, вам нужно отбросить одно из предположений.
Если оставить предположение № 1 и отказаться от предположения № 2, вы получите variable-width (или многобайтовая ) кодировка .На сегодняшний день наиболее популярным кодированием переменной ширины является UTF-8.
Предположение об отбрасывании # 1 и сохранение предположения # 2 дает вам кодирование широких символов .Unicode и UCS-2 были изначально разработаны для использования 16-битного кодирования с фиксированной шириной, что позволило бы получить 65 536 символов.Первые пользователи Unicode, такие как Sun (для Java) и Microsoft (для NT), использовали UCS-2.
Однако спустя несколько лет стало понятно, что даже , что не было 'Это достаточно для всех, поэтому диапазон кодов Unicode был расширен.Теперь, если вам нужна кодировка фиксированной ширины, вы должны использовать UTF-32.
Но Sun и Microsoft написали огромные API-интерфейсы, основанные на 16-битных символах, и не были в восторге от переписывания их для 32-немного.К счастью, по-прежнему существовал блок из 2048 неназначенных символов из исходной 65,536-символьной «Базовой многоязычной плоскости», которую можно было назначить в качестве «суррогатов» для использования в парах для представления дополнительных символов: формы кодирования UTF-16.К сожалению, UTF-16 не соответствует ни из двух исходных допущений: он не-8-битный и переменной ширины.
В итоге:
ИспользованиеUTF-8, когда важно предположение о 8-битных единицах кода.
Это относится к:
- Имена файлов и связанные вызовы ОС в системах Unix, в которых установленытрадиция допускает кодирование переменной ширины, но не может принимать
'\x00
байтов в строках и, следовательно, не может использовать UTF-16 или UTF-32.На самом деле UTF-8 изначально был предназначен для ОС на базе Unix (Plan 9). - Протоколы связи, разработанные на основе потоков октетов.
- Все, что требует двоичногосовместимость с US-ASCII, но не дает специальной обработки значениям байта выше 127.
Используйте UTF-32, когда важно допущение кодирования с фиксированной шириной.
Это полезно, когда вы заботитесь о свойствах символов в отличие от их кодировки, таких как эквиваленты Unicode для функций ctypes.h
, таких как isalpha
, isdigit
, toupper
,и т. д.
Используйте UTF-16, когда ни одно из предположений не является столь важным, но ваша платформа использовала UCS-2.
Вы пишете для Windows или для.NET Framework предназначен для этого?Для Java?Тогда UTF-16 - ваш тип строки по умолчанию;может также использовать его.
Поскольку вы используете C #, все ваши строки будут закодированы в UTF-16.ASP.NET будет кодировать фактические HTML-страницы в UTF-8, но это делается негласно, и вам не нужно об этом заботиться.
Соображения о размере
Для трех форм кодирования UTF требуетсяразличные объемы памяти для представления символа:
- Символам от U + 0000 до U + 007F (ASCII) требуется 1 байт в UTF-8, 2 байта в UTF-16 или 4 байта в UTF-32.
- Символы от U + 0080 до U + 07FF (символы IPA, греческий, кириллица, армянский, иврит, арабский, сирийский, тхана, нко) требуют 2 байта в UTF-8, 2 байта в UTF-16 или 4 байта вUTF-32.
- Символы от U + 0800 до U + FFFF (остальная часть BMP, в основном для азиатских языков) требуют 3 байта в UTF-8, 2 байта в UTF-16 или 4 байта в UTF-32.
- Символы U + 10000 до U + 10FFFF требуют 4 байта во всех трех формах кодирования.
Таким образом, если вы хотите сэкономить место, используйте UTF-8, если вашсимволы в основном ASCII или UTF-16, если ваши символы в основном азиатские.