Комментарии 27
Как и в России, в Японии остались сайты с однобайтовой кодировкой, переводим текст в UTF-8:
Какая же она однобайтовая? Она многобайтовая, как и UTF-8, почти все, кроме ASCII как раз в 2 байта кодируется.
Есть такая особенность у японцев: текст может быть записан двумя способами — так называемая «полная длина» (Zen-Kaku) и «половина длины» (Han-Kaku).
Стоит добавить, что в целом в шрифтах сильно поощряется моноширинность. Hankaku — это по сути те же codepoints, что в ASCII — но за счет форсируемого моноширинного шрифта они становятся ровно в половину знакоместа.
Но особенно японцы любят зен-каку цифры
Ларчик просто открывается: во всеми любимой операционной системе они вводятся по умолчанию при включенном Japanese IME. Как и full-width скобочки, точки, двоеточия, вопросительные/восклицательные и всякие такие знаки препинания.
Адрес верный, но чтобы его понимал, например, Curl, он должен быть закодирован:
Адрес надо URL-encode'ить в любом случае, японский ли это или нет. И тем более крайне странно использовать такую выборочную функцию.
без дополнительных инструментов добавлять разные украшения: ♪♫☆★「」︎♡.
но он ограничен 3 байтами на символ и не содержит 4-байтовые эмодзи
Из того, что вы привели, ни один символ не является расширенным 4-байтовым emoji. Все это прекрасно кодируется в 3-байтовый UTF-8. Я понимаю, что у вас сохранить не получилось из-за странностей хабрового движка, но зачем народ в заблужение-то вводить?
Какая же она однобайтовая?
Она действительно 1-2 байтовая. Спасибо что поправили.
И тем более крайне странно использовать такую выборочную функцию.
Если кодировать весь адрес, то будут закодированы также :// и другие символы, в результате, получим не работающую ссылку.
Более того даже в спецификации этой функции написано что кодироваться должна именно часть, как правило передаваемые параметры: http://php.net/manual/ru/function.urlencode.php Поэтому нужно именно выборочно.
Из того, что вы привели, ни один символ не является расширенным 4-байтовым emoji. Все это прекрасно кодируется в 3-байтовый UTF-8.
Нельзя. Конечно нельзя. Если адрес символа зарезервирован на 4 байтах, перевести его в 3 байта невозможно. Убрав 1 байт вы получите просто другой символ. Хабр 4 байта не сохраняет.
Поэтому нужно именно выборочно.
Но не так же! Собственно, даже в приведенном вами PHP manual написано: разумеется, нужно понимать семантику кодируемого и, как правило, разделять URL на составные части и кодировать по частям. Причем разные части кодируются по разному: домен — в punycode, path — percent-encoding с одним набором «запрещенных» ASCII символов, query — другим, fragment — остается в unicode (если речь не о CURL, скажем, а о каких-то браузерах). То, что предлагаете вы — просто неверно (а местами и опасно). Попробуйте закодировать, скажем, какой-нибудь http://日本語.jp/ вашей функцией — я посмотрю, что получится.
Если адрес символа зарезервирован на 4 байтах, перевести его в 3 байта невозможно.
Это все отлично, только для демонстрации этого вы используете 3-байтовые символы. Я понимаю, что вставить напрямую не удалось — ну так вставьте картинками, или добавьте ссылку на какой-нибудь сервис, корректнее работающий с unicode, или еще что-нибудь. Пока получается, что примеры в статье несколько противоречат содержимому.
С UTF-8 никаких проблем при такой некорректной конфигурации заметно не будет, так что подобные уязвимости, проявляющиеся только с «экзотическими» мультибайтными кодировками могут присутствовать в массе продуктов.
Вообще в целом вы затрагиваете очень непростую тему и к ней нельзя относиться так легко — мол, два регэкспа и вперед. Тема связана с нормализацией и сравнением строк в языке, где правила этого самого сравнения сильно отличаются от европейских и ожидания людей тоже отличаются.
Например, огромная туча людей будет справедливо считать, что 緑, みどり и ミドリ (а зачастую и "midori") — это одно и то же. И будут в целом правы. Это примерно как на русском языке считать, что "зелёный", "зеленый" и "ЗЕЛЕНЫЙ" — это одно и то же.
Есть куда более сложные примеры — когда нужно считать фонетические эквиваленты. Например, то же самое こんにちは люди пишут иногда как こんにちわ ("как слышу — так и пишу") или даже こにちは, например, пропустив двойную "n".
А иногда, например, когда речь идет об обработке баз данных с именами-фамилиями, так наоборот нельзя делать ни в коем случае, потому что 旭保 ("защитница утреннего солнца") и 朗穂 ("ясная голова") — две совершенно разных девушки, хотя и то, и другое произносится как "Akiho". И эти случаи надо отдельно выделять и оформлять подобным образом.
Продолжать можно еще очень долго.
— Моя фамилия Ге, — сказал француз китайцу.
— В китайском языке два иероглифа Ге, но, к сожалению, ни один из них не подходит для фамилии.
— Почему?
— Потому что один имеет значение «колесо», а другой передает звук, с которым лопается мочевой пузырь осла.
— А что плохого в колесе?
— Мужское имя не может быть круглым. Для твоего имени мы возьмем иероглиф Шэ, означающий «клавиатура», «корнеплод», «страница», а также прилагательное «бесснежный» и дополним его иероглифом Нгу, означающим мужской род. В конце я пишу иероглиф Мо — «девственный».
— Но это, мягко говоря, не совсем…
— Никто не будет считать тебя девственником, просто без иероглифа Мо иероглифы Ше-Нгу означают «сбривающий мамины усы».
— Хорошо, теперь я напишу твое имя.
— Моя фамилия Го.
— Отлично, я начну твою фамилию с буквы G.
— Что означает буква G?
— У нас, европейцев, сами по себе буквы ничего не значат, но чтобы проявить к тебе уважение, я поставлю перед G букву H — во французском она все равно не читается.
— Отлично! Дальше O?
— Нет, чтобы показать, что G — произносится как Г, а не как Х, надо после G поставить букву U, а также H — чтобы показать, что U не читается сама по себе, а только показывает, как правильно читать G, и буквы EY, показывающие, что слово не длинное и скоро закончится.
— Hguhey… дальше O?
— Нет, О во французском произносится как А или Ё, в зависимости от стоящих по соседству букв, ударения и времени года. Твое чистое О записывается как AUGHT, но слово не может кончаться на T, поэтому я добавлю нечитаемое окончание NGER. Вуаля!
Русский лингвист поставил бокал на стол, взял листочек и написал «Го» и «Ге».
— И всё?
— Да.
Француз с китайцем почесали в затылке.
— Хорошо, а какая у тебя фамилия?
— Щекочихин-Крестовоздвиженский.
— А давайте просто выпьем? — первым нашёлся китаец.
Русский кивнул и француз с облегчением поднял тост за шипящие дифтонги.
В обычных предложениях никто массово опечаток не делает (все пишут «ha», произносят «wa» и никакого когнитивного диссонанса не испытывают). С приветствием же проблема в том, что оно как бы полноценным предложением не является и устоялось в такой форме чисто по историческим причинам. Все на автомате произносят и никто даже не задумывается о том, что это значит дословно. И точно так же на автомате иногда пишут. Я в свое время даже по входящей почте статистику считал — на 100 писем с приветствием эдак 5-7 «неверных» записей точно будет. Причем письма вполне от чистокровных японцев, не от каких-нибудь понаехавших студентов.
Гораздо хуже со всякими там «gasoline» (который выглядят страшно на записи — ガソリン), всякими там фамилиями типа «Волобуев» (которая становится «borobuebu») или с сосредоточением согласных типа «Мкртчян» (с другом могу представить).
но делать это для всех эмодзи ещё тот праздник :)
PHP-инструменты для японского языка