例如,我有:11100011 10000010 10100010
。它是:ア
的二进制文件;
它在UTF-8中的数字是:12450
如何从二进制中获取此数字?
答案 0 :(得分:1)
您显示的字节序列是字符的UTF-8编码版本。
您需要解码 UTF-8才能进入Unicode代码点。
对于这个确切的字节序列,以下位构成代码点:
11100011 10000010 10100010
**** ****** ******
因此,连接带星号的位,我们得到数字0011000010100010
,等于0x30a2或十进制12450。
有关如何解释编码的详细信息,请参阅Wikipedia description。
简而言之:如果在第一个字节中设置了第7位,那么同样设置的相邻位数(称为 m )(2)给出了此后的字节数代码点。从每个字节中提取的位数对于第一个字节是(8 - 1 - 1 - m ),对于每个后续字节是6位。所以我们得到(8 - 1 - 1 - 2)= 4 + 2 * 6 = 16位。
正如评论中指出的那样,有很多库可供您使用,因此您可能不需要自己实现它。
答案 1 :(得分:1)
在wikipedia page工作,我想出了这个:
unsigned utf8_to_codepoint(const char* ptr) {
if( *ptr < 0x80) return *ptr;
if( *ptr < 0xC0) throw unicode_error("invalid utf8 lead byte");
unsigned result=0;
int shift=0;
if( *ptr < 0xE0) {result=*ptr&0x1F; shift=1;}
if( *ptr < 0xF0) {result=*ptr&0x0F; shift=2;}
if( *ptr < 0xF8) {result=*ptr&0x07; shift=3;}
for(; shift>0; --shift) {
++ptr;
if (*ptr<0x7F || *ptr>=0xC0)
throw unicode_error("invalid utf8 continuation byte");
result <<= 6;
result |= *ptr&0x6F;
}
return result;
}
请注意,这是一个非常糟糕的实现(我非常怀疑它甚至编译),并解析了很多可能不应该的无效值。我这样做只是为了表明它比你想象的要难得多,并且你应该使用一个好的unicode库。