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

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

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

Изменить: взаимодействуя, я в основном имею в виду shell и libc.

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

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

Ответ 3

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

Для ответа на вопрос "Опасности" вам нужно указать, что вы подразумеваете под "взаимодействием". Вы имеете в виду взаимодействие с оболочкой, с libc или с самим ядром?

Ответ 4

Современные Unix используют 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.

Ответ 5

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

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

Ответ 6

Да, это по соображениям совместимости. UTF-8 обратно сопоставляется с ASCII. Linux/Unix были основаны на ASCII, поэтому он просто сделал/имеет смысл.

Ответ 7

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

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

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

Ответ 8

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