Intereting Posts
выбор DIV, которые находятся внутри неупорядоченного списка и элемента списка с помощью простого html dom Google Oauth для YouTube: почему я получаю код «Undefined index: oauth_token» (код Jim S.) Получение сообщений из очереди (ов) RabbitMQ Возможно ли динамически перезагрузить PHP-код во время работы скрипта? Случайная несогласованность путей файлов PHP на Mac / MAMP? Как загрузить изображение PHP и вставить путь в MySQL? PHP array_multisort не сортирует мой многомерный массив, как ожидалось Отправка заголовка Soap с помощью WSDL Soap Request с PHP вложение нескольких значений в опции <select> Как выводить данные при использовании $ stmt-> fetch (PDO :: FETCH_ASSOC); WordPress Theme Customizer – добавление области для перемещения пользователей и организации виджетов Доктрина – подзапрос из Строгая проверка и фильтрация HTML в PHP php сортирует ассоциативные массивы ключами, что эти ключи существуют в другом массиве Как получить / установить session_id () или он должен быть сгенерирован автоматически?

Как получить номер кодовой точки для заданного символа в строке utf-8?

Я хочу получить коды UCS-2 для данной строки UTF-8. Например, слово «привет» должно стать чем-то вроде «0068 0065 006C 006C 006F». Обратите внимание, что символы могут быть с любого языка, включая сложные скрипты, такие как восточно-азиатские языки.

Таким образом, проблема сводится к «преобразованию заданного символа в его кодовую точку UCS-2»,

Но как? Пожалуйста, любая помощь будет очень высоко оценена, так как я очень спешу.

заранее спасибо


Транскрипция ответа опроса, отправленного в качестве ответа

Спасибо за ваш ответ, но это нужно сделать в PHP версии 4 или 5, но не в 6.

Строка будет пользователем, из поля формы.

Я хочу реализовать PHP-версию utf8to16 или utf8decode, например

function get_ucs2_codepoint($char) { // calculation of ucs2 codepoint value and assign it to $hex_codepoint return $hex_codepoint; } 

Можете ли вы помочь мне с PHP или это можно сделать с PHP с упомянутой выше версией?

Еще раз спасибо.

Solutions Collecting From Web of "Как получить номер кодовой точки для заданного символа в строке utf-8?"

Скотт Рейнэн написал функцию преобразования UTF-8 в Unicode . Я нашел это, глядя на документацию PHP .

 function utf8_to_unicode( $str ) { $unicode = array(); $values = array(); $lookingFor = 1; for ($i = 0; $i < strlen( $str ); $i++ ) { $thisValue = ord( $str[ $i ] ); if ( $thisValue < ord('A') ) { // exclude 0-9 if ($thisValue >= ord('0') && $thisValue <= ord('9')) { // number $unicode[] = chr($thisValue); } else { $unicode[] = '%'.dechex($thisValue); } } else { if ( $thisValue < 128) $unicode[] = $str[ $i ]; else { if ( count( $values ) == 0 ) $lookingFor = ( $thisValue < 224 ) ? 2 : 3; $values[] = $thisValue; if ( count( $values ) == $lookingFor ) { $number = ( $lookingFor == 3 ) ? ( ( $values[0] % 16 ) * 4096 ) + ( ( $values[1] % 64 ) * 64 ) + ( $values[2] % 64 ): ( ( $values[0] % 32 ) * 64 ) + ( $values[1] % 64 ); $number = dechex($number); $unicode[] = (strlen($number)==3)?"%u0".$number:"%u".$number; $values = array(); $lookingFor = 1; } // if } // if } } // for return implode("",$unicode); } // utf8_to_unicode 

Используйте существующую утилиту, такую ​​как iconv , или любые библиотеки, в которых используется язык, который вы используете.

Если вы настаиваете на сворачивании собственного решения, прочитайте в формате UTF-8 . В принципе, каждая точка кода хранится как 1-4 байта, в зависимости от значения кодовой точки. Диапазоны следующие:

  • U + 0000 – U + 007F: 1 байт: 0xxxxxxx
  • U + 0080 – U + 07FF: 2 байта: 110xxxxx 10xxxxxx
  • U + 0800 – U + FFFF: 3 байта: 1110xxxx 10xxxxxx 10xxxxxx
  • U + 10000 – U + 10FFFF: 4 байта: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Где каждый x – бит данных. Таким образом, вы можете указать, сколько байтов составляет каждую кодовую точку, если посмотреть на первый байт: если он начинается с 0, это 1-байтовый символ. Если он начинается с 110, это двухбайтовый символ. Если он начинается с 1110, это 3-байтовый символ. Если он начинается с 11110, это 4-байтовый символ. Если он начинается с 10, это не начальный байт многобайтового символа. Если он начинается с 11111, это недопустимый символ.

Как только вы выясните, сколько байтов в персонаже, это просто вопрос, если бит немного крутится. Также обратите внимание, что UCS-2 не может представлять символы выше U + FFFF.

Поскольку вы не указали язык, вот пример кода C (ошибка проверки опущена):

 wchar_t utf8_char_to_ucs2(const unsigned char *utf8) { if(!(utf8[0] & 0x80)) // 0xxxxxxx return (wchar_t)utf8[0]; else if((utf8[0] & 0xE0) == 0xC0) // 110xxxxx return (wchar_t)(((utf8[0] & 0x1F) << 6) | (utf8[1] & 0x3F)); else if((utf8[0] & 0xF0) == 0xE0) // 1110xxxx return (wchar_t)(((utf8[0] & 0x0F) << 12) | ((utf8[1] & 0x3F) << 6) | (utf8[2] & 0x3F)); else return ERROR; // uh-oh, UCS-2 can't handle code points this high } 

Я удивлен, потому что я просто дал эту проблему студентам на выпускном экзамене. Вот эскиз UTF-8:

 hex binary UTF-8 binary 0000-007F 00000000 0abcdefg => 0abcdefg 0080-07FF 00000abc defghijk => 110abcde 10fghijk 0800-FFFF abcdefgh ijklmnop => 1110abcd 10efghij 10klmnop 

И вот код C99:

 static void check(char c) { if ((c & 0xc0) != 0xc0) RAISE(Bad_UTF8); } uint16_t Utf8_decode(char **p) { // return code point and advance *p char *s = *p; if ((s[0] & 0x80) == 0) { (*p)++; return s[0]; } else if ((s[0] & 0x40) == 0) { RAISE (Bad_UTF8); return ~0; // prevent compiler warning } else if ((s[0] & 0x20) == 0) { if ((s[0] & 0xf0) != 0xe0) RAISE (Bad_UTF8); check(s[1]); check(s[2]); (*p) += 3; return ((s[0] & 0x0f) << 12) + ((s[1] & 0x3f) << 6) + ((s[2] & 0x3f)); } else { check(s[1]); (*p) += 2; return ((s[0] & 0x1f) << 6) + ((s[1] & 0x3f)); } } 

PHP-код (который принимает действительный utf-8, не проверяет недействительные utf-8):

 function ord_utf8($c) { $b0 = ord($c[0]); if ( $b0 < 0x10 ) { return $b0; } $b1 = ord($c[1]); if ( $b0 < 0xE0 ) { return (($b0 & 0x1F) << 6) + ($b1 & 0x3F); } return (($b0 & 0x0F) << 12) + (($b1 & 0x3F) << 6) + (ord($c[2]) & 0x3F); }