Как Вы создали бы строку всех символов UTF-8?

Существует много способов представить +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);

5
задан ScottMcGready 14 April 2014 в 02:26
поделиться

4 ответа

Вы можете использовать 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")

.
6
ответ дан 13 December 2019 в 19:23
поделиться

Я не уверен, что вы можете сделать это программно, в основном потому, что существует разница между кодовой точкой Unicode и символом. См. http://www.unicode.org/standard/where , где приведены несколько примеров символов, представленных комбинацией кодовых точек.

Некоторые кодовые точки не имеют смысла сами по себе и могут использоваться только в сочетании с другим символом (подумайте о акцентах). См. http://www.unicode.org/charts/charindex.html для получения списка кодовых точек и просмотрите раздел со всеми «объединяющими» кодовыми точками.

Кроме того, для использования в тестировании приложений вам понадобится что-то еще, помимо списка возможных кодовых точек UTF-8, а именно несколько недопустимых / искаженных последовательностей UTF-8, из которых ваше приложение должно иметь возможность корректно восстанавливаться.

Для этого взгляните на стресс-тест Unicode Маркуса Куна .

4
ответ дан 13 December 2019 в 19:23
поделиться

:) Конечно, последний вариант не работает. \x последовательность относится к строкам с двойными кавычками.

что не так с $char = chr(196).chr(128); ? с chr($a).chr($b) я имею ввиду.

0
ответ дан 13 December 2019 в 19:23
поделиться

Я быстро перевел это с 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, а также есть несколько других пробелов для объединения символов и зарезервированных символов.

1
ответ дан 13 December 2019 в 19:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: