UCS2 / HexEncoded caracteres a UTF-8 en php
Pregunta
he hecho una pregunta previamente para obtener una cadena UCS-2 / HexEncoded de UTF-8, y tengo la ayuda de algunos chicos en el siguiente enlace.
Pero ahora tengo que conseguir el UTF-8 correcta de una cadena UCS-2 / HexEncoded en PHP.
En las siguientes cadenas:
00480065006C006C006F volverá 'Hola'
06450631062d0628064b06270020063906270644064500200021 volverá (! مرحبا عالم) en árabe
Solución
Puede recomponer un Hex-representación mediante la conversión de los caracteres hexadecimales con hexdec () , volver a empaquetar los caracteres de componentes, y luego usando mb_convert_encoding () convertir de UCS- 2 en UTF-8. Como ya he mencionado en mi respuesta a su otra pregunta, usted todavía tiene que tener cuidado con la codificación de salida, aunque aquí se ha solicitado específicamente UTF-8, por lo que vamos a utilizar para la próxima muestra.
He aquí una muestra que hace el trabajo de convertir UCS-2 en Hex a UTF-8 en forma de cadena nativa. Como PHP actualmente no se entrega con una función hex2bin () , que haría las cosas muy fácil, vamos a utilizar la publicada en el enlace de referencia al final. He le cambió el nombre a local_hex2bin () en caso de que esté en oposición con una futura versión de PHP o con una definición en algún otro código de 3 ª parte que incluya en su proyecto.
<?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>';
?>
A nivel local, llamé a esta página muestra UCS2HexToUTF8.php, y luego se usa una cadena de consulta para establecer la salida.
UCS2HexToUTF8.php?06450631062d0628064b06270020063906270644064500200021
--
encoding: UTF-8
query string: 06450631062d0628064b06270020063906270644064500200021
converted string: مرحبًا عالم !
UCS2HexToUTF8.php?00480065006C006C006F
--
output encoding: UTF-8
query string: 00480065006C006C006F
converted string: Hello
Aquí está el enlace a la fuente original de la , función hex2bin ().
PHP: bin2hex (), comentario # 86123 @ php.net
Además, como se ha señalado en mis comentarios antes de la llamada a mb_convert_encoding () , es probable que desee para tratar de detectar qué endian pedidos está en uso por la fuente, especialmente si su aplicación tiene partes donde uno o más CPU en un servidor difieren del resto por la orientación.
Aquí hay un enlace que puede ayudar a identificar las marcas de orden de bytes (BOM).
@ Wikipedia
Otros consejos
Una conversión más precisa de UCS-2 a 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;
}
El problema en respuesta seleccionada es que fue dividido por 2 en lugar de 4 lo que causaría la conversión de 00 como nulo y hará que esta a aparecer cuando se utiliza en html valores de atributos como el título = "" o alt = ""