我想获得给定UTF-8字符串的UCS-2代码点.例如,单词"hello"应该变成类似"0068 0065 006C 006C 006F"的字样.请注意,这些字符可以来自任何语言,包括东亚语言等复杂脚本.
因此,问题归结为"将给定字符转换为其UCS-2代码点"
但是怎么样?请非常感谢任何形式的帮助,因为我非常着急.
提问者的回复转录作为答案发布
感谢您的回复,但需要在PHP v 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上面提到的版本来完成?
使用现有的实用程序,例如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开头,那么它是一个2字节的字符.如果它以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 }
Scott Reynen编写了一个将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
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); }