¿Cómo crearías una cadena de todos los caracteres UTF-8?

Hay muchas maneras de representar el +1 millón de caracteres UTF-8 . Tome la capital latina “A” con macron ( Ā ). Este es el punto de código Unicode U+0100 , el número hexadecimal 0xc4 0x80 , el número decimal 196 128 y el binario 11000100 10000000 .

Me gustaría crear una colección de los primeros 65.535 caracteres UTF-8 para usar en aplicaciones de prueba. Todos estos son caracteres unicode hasta el punto de código U+FFFF (byte3).

¿Es posible hacer algo como un bucle for($x=0) y luego convertir el decimal resultante a otra base (como el hex) que permitiría la creación del carácter unicode coincidente?

Puedo crear el valor Ā usando algo como esto:

 $char = "\xc4\x80"; // or $char = chr(196).chr(128); 

Sin embargo, no estoy seguro de cómo convertir esto en un proceso automatizado.

 // fail! $char = "\x". dechex($a). "\x". dexhex($b); 

Puede aprovechar iconv (u otras funciones) para convertir un número de punto de código en una cadena UTF-8:

 function unichr($i) { return iconv('UCS-4LE', 'UTF-8', pack('V', $i)); } $codeunits = array(); for ($i = 0; $i<0xD800; $i++) $codeunits[] = unichr($i); for ($i = 0xE000; $i<0xFFFF; $i++) $codeunits[] = unichr($i); $all = implode($codeunits); 

(Evité el rango sustituto 0xD800-0xDFFF ya que no son válidos para poner en UTF-8 ellos mismos, eso sería "CESU-8").

No estoy seguro de que pueda hacer esto programáticamente, principalmente porque hay una diferencia entre un punto de código Unicode y un personaje. Consulte http://www.unicode.org/standard/where para ver algunos ejemplos de personajes que están representados por una combinación de puntos de código.

Algunos puntos de código no tienen sentido por sí solos y solo se pueden usar junto con otro personaje (piense en los acentos). Consulte http://www.unicode.org/charts/charindex.html para obtener una lista de puntos de código, y mire la sección con todos los puntos de código “combinados”.

Además, para usar en aplicaciones de prueba, necesitaría algo más, además de una lista de posibles puntos de código UTF-8, a saber, varias secuencias UTF-8 no válidas / malformadas que su aplicación necesita para poder recuperarse correctamente.

Para esto, eche un vistazo a la prueba de esfuerzo Unicode de Markus Kuhn .

Rápidamente lo traduje de C, pero debería darte la idea:

 function encodeUTF8( $inValue ) { $result = ""; if ( $inValue < 0x00000080 ) { $result .= chr( $inValue ); $extra = 0; } else if ( $inValue < 0x00000800 ) { $result .= chr( 0x00C0 | ( ( $inValue >> 6 ) & 0x001F ) ); $extra = 6; } else if ( $inValue < 0x00010000 ) { $result .= chr( 0x00E0 | ( ( $inValue >> 12 ) & 0x000F ) ); $extra = 12; } else if ( $inValue < 0x00200000 ) { $result .= chr( 0x00F0 | ( ( $inValue >> 18 ) & 0x0007 ) ); $extra = 18; } else if ( $inValue < 0x04000000 ) { $result .= chr( 0x00F8 | ( ( $inValue >> 24 ) & 0x0003 ) ); $extra = 24; } else if ( $inValue < 0x80000000 ) { $result .= chr( 0x00FC | ( ( $inValue >> 30 ) & 0x0001 ) ); $extra = 30; } while ( $extra > 0 ) { $result .= chr( 0x0080 | ( ( $inValue >> ( $extra -= 6 ) ) & 0x003F ) ); } return $result; } 

La lógica es sólida, pero no estoy seguro sobre el php, así que asegúrese de revisarlo. Nunca he tratado de usar chr esta manera.

Hay muchos valores que no desearía codificar, como 0xD000-0xDFFF, 0xE000-0xF8FF y 0xFFF0-0xFFFF, y existen otros espacios para combinar caracteres y caracteres reservados.

🙂 por supuesto, el último no funcionaría. \ x secuencia pertenece a las cadenas de comillas dobles.

qué pasa con $char = chr(196).chr(128); ? con chr ($ a) .chr ($ b) quiero decir.

 >6,1<<7|191&$n): ($n<(1<<16)?pack($f,224|$n>>12,1<<7|63&$n>>6,1<<7|63&$n): ($n<(1<<20|1<<16)?pack($f,240|$n>>18,1<<7|63&$n>>12,1<<7|63&$n>>6,1<<7|63&$n):''))); } echo implode('',array_map('chr_utf8',range(0,65535))); // Output a big string, you can increase the range to 1114111…