我想获得给定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完成?
答案 0 :(得分:11)
使用现有的实用程序,例如iconv,或者您正在使用的语言附带的任何库。
如果您坚持推出自己的解决方案,请阅读UTF-8格式。基本上,每个代码点都存储为1-4个字节,具体取决于代码点的值。范围如下:
其中每个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
}
答案 1 :(得分:8)
Scott Reynen向convert UTF-8 into Unicode写了一个函数。我发现它看着PHP documentation。
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
答案 2 :(得分:5)
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);
}
答案 3 :(得分:4)
我很开心因为我刚刚给期末考试的学生这个问题。这是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));
}
}