Почему при взаимодействии со средой UNIX / Linux используется кодировка UTF-8? - PullRequest
11 голосов
/ 03 октября 2008

Я знаю, что это принято, но почему? Существуют ли реальные технические причины, по которым любой другой способ был бы действительно плохой идеей, или он просто основан на истории кодирования и обратной совместимости? Кроме того, в чем опасность не использования UTF-8, а какой-либо другой кодировки (прежде всего, UTF-16)?

Редактировать: Под взаимодействием я в основном имею в виду shell и libc.

Ответы [ 8 ]

15 голосов
/ 03 октября 2008

Частично потому, что файловые системы ожидают, что байты NUL ('\ 0') завершают имена файлов, поэтому UTF-16 не будет работать хорошо. Вам нужно было бы изменить много кода, чтобы сделать это изменение.

8 голосов
/ 03 октября 2008

Как упоминает Джонатан-Леффлер, основной проблемой является нулевой символ ASCII. C традиционно ожидает, что строка завершается нулем. Поэтому стандартные строковые функции C будут подавлять любой символ UTF-16, содержащий байт, эквивалентный нулю ASCII (0x00). Хотя вы, безусловно, можете программировать с поддержкой широких символов, UTF-16 не подходит для внешней кодировки Unicode в именах файлов, текстовых файлах, переменных среды .

Кроме того, UTF-16 и UTF-32 имеют ориентацию как с прямым, так и с обратным порядком байтов. Чтобы справиться с этим, вам понадобятся либо внешние метаданные, такие как тип MIME, либо знак байтовой ориентации . Это отмечает,

Где UTF-8 используется прозрачно в 8-битные среды, использование спецификации будет мешать любому протоколу или формат файла, который ожидает конкретного Символы ASCII в начале, такие как использование "#!" из на начало сценариев оболочки Unix.

Предшественник UTF-16, который назывался UCS-2 и не поддерживал суррогатные пары, имел те же проблемы . UCS-2 следует избегать.

2 голосов
/ 03 октября 2008

Современные Unixes используют UTF-8, но это не всегда было так. На RHEL2 - которому всего несколько лет - по умолчанию

$ locale
LANG=C
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=
Предполагается, что языковой стандарт C / POSIX будет 7-битной ASCII-совместимой кодировкой.

Однако, как заявил Джонатан Леффлер, любая кодировка, которая допускает NUL-байты в последовательности символов, не работает в Unix, поскольку системные API-интерфейсы игнорируют локали; все строки считаются байтовыми последовательностями, оканчивающимися на \ 0.

2 голосов
/ 03 октября 2008

Я считаю, что это в основном обратная совместимость, которую дает UTF8 с ASCII.

Чтобы ответить на вопрос «опасности», вам необходимо указать, что вы подразумеваете под «взаимодействием». Вы имеете в виду взаимодействие с оболочкой, с libc или с самим ядром?

1 голос
/ 06 октября 2008

Я полагаю, что когда Microsoft начала использовать двухбайтовую кодировку, символы выше 0xffff не были назначены, поэтому использование двухбайтовой кодировки означало, что никому не приходилось беспокоиться о символах разной длины.

Теперь, когда за пределами этого диапазона есть символы, так что вам все равно придется иметь дело с символами разной длины, зачем кому-то использовать UTF-16? Я подозреваю, что Microsoft приняла бы другое решение, если бы сегодня они отказались от поддержки Unicode.

0 голосов
/ 03 октября 2008

Я думаю, это потому, что программы, которые ожидают ввода ASCII, не смогут обрабатывать кодировки, такие как UTF-16. Для большинства символов (в диапазоне 0-255) эти программы будут видеть старший байт в виде символа NUL / 0, который используется во многих языках и системах для обозначения конца строки. Этого не происходит в UTF-8, который был разработан, чтобы избежать встроенных NUL и быть независимым от порядка следования байтов.

0 голосов
/ 03 октября 2008

Я думал, что 7-битный ASCII в порядке.

Серьезно, Unicode является относительно новым в схеме вещей, и UTF-8 обратно совместим с ASCII и использует меньше места (наполовину) для типичных файлов, поскольку использует от 1 до 4 байтов на кодовую точку (символ), тогда как UTF-16 использует 2 или 4 байта на кодовую точку (символ).

UTF-16 предпочтительнее для внутреннего использования программы из-за более простой ширины. Его предшественник UCS-2 составлял ровно 2 байта для каждой кодовой точки.

0 голосов
/ 03 октября 2008

Да, это из соображений совместимости. UTF-8 обратно совместим с ASCII. Linux / Unix были основаны на ASCII, так что это имело смысл.

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