4

以前、UTF-8からUCS-2 / HexEncoded文字列を取得するように質問しましたが、次のリンクで何人かの人から助けを得ました。

UCS2/HexEncoded文字

しかし、ここで、PHPのUCS-2/HexEncoded文字列から正しいUTF-8を取得する必要があります。

次の文字列の場合:

00480065006C006C006Fは「こんにちは」を返します

06450631062d0628064b06270020063906270644064500200021はアラビア語で(!مرحباعالم)を返します

4

2 に答える 2

3

hexdec()で16 進文字を変換し、コンポーネント文字を再パックしてから、 mb_convert_encoding()を使用して UCS-2 から UTF-8 に変換することにより、16 進数表現を再構成できます。他の質問への回答で述べたように、ここでは特に UTF-8 を要求しているため、出力エンコーディングには注意する必要があるため、今後のサンプルではそれを使用します。

これは、16 進数の UCS-2 をネイティブ文字列形式の UTF-8 に変換する作業を行うサンプルです。PHP には現在、非常に簡単なhex2bin()関数が同梱されていないため、最後の参照リンクに掲載されているものを使用します。PHP の将来のバージョンまたはプロジェクトに含める他のサードパーティ コードの定義と競合する場合に備えて、名前をlocal_hex2bin()に変更しました。

<?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()への呼び出しの前に私のコメントで述べたように、ソースで使用されているエンディアン順序を試して検出することをお勧めします。特に、1 つのサーバー上の 1 つ以上の CPU が異なる部分がアプリケーションにある場合は特にそうです。残りはオリエンテーションによって。

バイト オーダー マーク (BOM) を識別するのに役立つリンクを次に示します。
バイトオーダーマーク@ウィキペディア

于 2010-01-05T17:24:09.077 に答える
1

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;
}

選択した回答の問題は、4 ではなく 2 で除算されたため、00 が null として変換され、title="" または alt="" などの html 属性値で使用されたときにこれが表示されることです。

于 2018-10-02T13:48:56.963 に答える