Почему «й» (и-краткая) в UTF-8 файловой системе Linux занимает 4 байта?
На сервере CentOS 7.8 лежат файлы с именами кириллицей. Например, Юрий.jpg
В имени этого файла первые три буквы по 2 байта, а «Й» почему-то аж 4:
%D0%AE%D1%80%D0%B8%D0%B8%CC%86.jpg
А когда приходит веб-запрос c кириллицей, все буквы, включая «й» – по 2 байта:
%D0%AE%D1%80%D0%B8%D0%B9.jpg
(Оба примера через php urlencode())
Требуется по веб-запросу с параметром «Юрий» найти соответствующий локальный файл. Как лучше решить эту задачу с неоднозначностью кодирования некоторых букв?
Пока думаю переименовать файлы, заменяя длинную последовательность для «Й» на нормальные 2 байта. Видимо, файлы так переносили на сервер, что некоторые символы так исказились. Если создать новый файл с русским именем, проблемы нет - каждый символ по 2 байта.
Но неясно, какие ещё символы исказились. Вряд ли только «й».
Спасибо hint000 за разъяснение со ссылкой на Алгоритмы Нормализации в Unicode — там как раз в таблице пример с «й». Узнал про NFD, NFC.
В итоге в PHP при поиске файла с названием кириллицей по принятому параметру нормализую параметр в NFD (в котором оказались локальные файлы) с помощью класса Normalizer:
Normalizer::normalize($cyrillic_name, Normalizer::FORM_D)
// преобразует имя "Юрий" из
// "%D0%AE%D1%80%D0%B8%D0%B9"
// в
// "%D0%AE%D1%80%D0%B8%D0%B8%CC%86" – как в локальных файлах оказалось.
Потому что "й" состоит из двух глифов: "и" + глифа сверху нее, которые при выводе на экран комбинируются в один символ "й".
И криминала в этом совершенно нет.