UCS2 / HexEncoded символы в UTF8 в php - PullRequest
3 голосов
/ 05 января 2010

Ранее я задавал вопрос, чтобы получить строку UCS-2 / HexEncoded от UTF-8, и мне помогли некоторые парни по следующей ссылке.

UCS2 / HexEncoded символов

Но теперь мне нужно получить правильный UTF-8 из строки UCS-2 / HexEncoded в PHP.

Для следующих строк:

00480065006C006C006F вернет «Привет»

06450631062d0628064b06270020063906270644064500200021 вернется (! مرحبا عالم) на арабском языке

Ответы [ 2 ]

3 голосов
/ 05 января 2010

Вы можете перекомпоновать шестнадцатеричное представление, преобразовав шестнадцатеричные символы с помощью hexdec () , перепаковав символы компонента, а затем используя mb_convert_encoding () для преобразования из UCS-2 в UTF-8. Как я уже упоминал в своем ответе на другой вопрос, вам все равно нужно быть осторожным с выходной кодировкой, хотя здесь вы специально запросили UTF-8, поэтому мы будем использовать ее для следующего примера.

Вот пример, который выполняет преобразование UCS-2 в Hex в UTF-8 в нативной строковой форме. Поскольку PHP в настоящее время не поставляется с функцией hex2bin () , которая упростит задачу, мы будем использовать ту, которая размещена по ссылке в конце. Я переименовал его в local_hex2bin () на всякий случай, если он конфликтует с будущей версией PHP или с определением в каком-либо другом стороннем коде, который вы включите в свой проект.

<?php
function local_hex2bin($h)
{
if (!is_string($h)) return null;
$r='';
for ($a=0; $a<strlen($h); $a+=2) { $r.=chr(hexdec($h{$a}.$h{($a+1)})); }
return $r;
};

header('Content-Type: text/html; charset=UTF-8');
mb_http_output('UTF-8');
echo '<html><head>';
echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
echo '</head><body>';
echo 'output encoding: '.mb_http_output().'<br />';
$querystring = $_SERVER['QUERY_STRING'];
// NOTE: we could substitute one of the following:
// $querystring = '06450631062d0628064b06270020063906270644064500200021';
// $querystring = '00480065006C006C006F';
$ucs2string = local_hex2bin($querystring);
// NOTE: The source encoding could also be UTF-16 here.
// TODO: Should check byte-order-mark, if available, in case
//       16-bit-aligned bytes are reversed.
$utf8string = mb_convert_encoding($ucs2string, 'UTF-8', 'UCS-2');
echo 'query string: '.$querystring.'<br />';
echo 'converted string: '.$utf8string.'<br />';
echo '</body>';
?>

Локально, я назвал этот пример страницы UCS2HexToUTF8.php, а затем использовал строку запроса для установки вывода.

UCS2HexToUTF8.php?06450631062d0628064b06270020063906270644064500200021
--
encoding: UTF-8
query string: 06450631062d0628064b06270020063906270644064500200021
converted string: مرحبًا عالم !

UCS2HexToUTF8.php?00480065006C006C006F
--
output encoding: UTF-8
query string: 00480065006C006C006F
converted string: Hello

Вот ссылка на исходный источник функции hex2bin () .
PHP: bin2hex (), комментарий # 86123 @ php.net

Кроме того, как отмечалось в моих комментариях перед вызовом mb_convert_encoding () , вы, вероятно, захотите попытаться определить, какой порядок следования байтов используется источником, особенно если ваше приложение содержит части, где один или несколько процессоров на одном сервере отличаются от остальных по ориентации.

Вот ссылка, которая может помочь вам определить метки порядка байтов (BOM).
Метка порядка байтов @ Википедия

0 голосов
/ 02 октября 2018

Более точное преобразование UCS-2 в UTF-8

function ucs2_to_utf8($h)
{
    if (!is_string($h)) return null;
    $r='';
    for ($a=0; $a<strlen($h); $a+=4) { $r.=chr(hexdec($h{$a}.$h{($a+1)}.$h{($a+2)}.$h{($a+3)})); }
    return $r;
}

Проблема в выбранном ответе состоит в том, что он был разделен на 2 вместо 4, что привело бы к преобразованию 00 в нулевое значение и приведет к появлению этого символа when, если он используется в значениях атрибутов html, таких как title = "" или alt = ""

...