UCS2 / HexEncoded символы в UTF8 в php

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

Символы UCS2 / HexEncoded

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

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

00480065006C006C006F вернет "Hello"

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


person mabukarim    schedule 05.01.2010    source источник
comment
Что не было достаточно ясным в ответах на ваш предыдущий вопрос?   -  person Jimmy Shelter    schedule 05.01.2010
comment
Мне нужно получить utf8 из шестнадцатеричной закодированной строки ucs2, я имею в виду, что мне нужно вернуться из шестнадцатеричной кодировки ucs2 в utf8   -  person mabukarim    schedule 05.01.2010


Ответы (2)


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

Вот пример, который выполняет работу по преобразованию UCS-2 в шестнадцатеричном формате в 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).
Метка порядка байтов @ Википедия

person meklarian    schedule 05.01.2010
comment
Есть более компактный способ сделать то же самое: $querystring = '06450631062d0628064b06270020063906270644064500200021'; $str = pack('H*', $querystring); $ucs2string = mb_convert_encoding($str, 'UTF-8', 'UCS-2'); - person Jay; 26.09.2012

Более точное преобразование 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 как null и появлению этого �, когда оно используется в значениях атрибутов html, таких как title = "" или alt = ""

person Mark Morgan Miranda    schedule 02.10.2018