Существует много способов представить +1 миллион символов UTF-8. Возьмите латинский капитал "A" с макроном (Ā
). Это - unicode кодовая точка U+0100
, шестнадцатеричное число 0xc4 0x80
, десятичное число 196 128
, и двоичный файл 11000100 10000000
.
Я хотел бы создать набор первых 65 535 символов UTF-8 для использования в тестировании приложений. Это все unicode символы до кодовой точки U+FFFF
(byte3).
Действительно ли возможно сделать что-то как a for($x=0)
цикл и затем преобразовывает получающееся десятичное число в другую основу (как шестнадцатеричное число), который позволил бы создание соответствия unicode символ?
Я могу создать стоимость Ā
использование чего-то вроде этого:
$char = "\xc4\x80";
// or
$char = chr(196).chr(128);
Однако я не уверен, как превратить это в автоматизированный процесс.
// fail!
$char = "\x". dechex($a). "\x". dexhex($b);
Вы можете использовать iconv
(или несколько других функций) для преобразования номера кодовой точки в строку 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);
(Я избегал суррогатного диапазона 0xD800-0xDFFF, поскольку они сами по себе не могут быть переведены в UTF-8; это будет "CESU-8")
.Я не уверен, что вы можете сделать это программно, в основном потому, что существует разница между кодовой точкой Unicode и символом. См. http://www.unicode.org/standard/where , где приведены несколько примеров символов, представленных комбинацией кодовых точек.
Некоторые кодовые точки не имеют смысла сами по себе и могут использоваться только в сочетании с другим символом (подумайте о акцентах). См. http://www.unicode.org/charts/charindex.html для получения списка кодовых точек и просмотрите раздел со всеми «объединяющими» кодовыми точками.
Кроме того, для использования в тестировании приложений вам понадобится что-то еще, помимо списка возможных кодовых точек UTF-8, а именно несколько недопустимых / искаженных последовательностей UTF-8, из которых ваше приложение должно иметь возможность корректно восстанавливаться.
Для этого взгляните на стресс-тест Unicode Маркуса Куна .
:) Конечно, последний вариант не работает. \x последовательность относится к строкам с двойными кавычками.
что не так с $char = chr(196).chr(128);
? с chr($a).chr($b) я имею ввиду.
Я быстро перевел это с C, но это должно дать вам идею:
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;
}
Логика правильная, но я не уверен насчет php, так что будьте обязательно проверьте это еще раз. Я никогда не пробовал использовать chr
таким образом.
Есть много значений, которые вы не хотели бы кодировать, например 0xD000-0xDFFF, 0xE000-0xF8FF и 0xFFF0-0xFFFF, а также есть несколько других пробелов для объединения символов и зарезервированных символов.