这个八位字节流是如何被解释为希伯来语UTF-8编码的



以下字节流被标识为UTF-8,它包含希伯来语句子:דירות לשותפים בתל אביב - הומלס。我正在试着理解编码。

ubuntu@ip-10-126-21-104:~$ od -t x1 homeless-title-fromwireshark_followed_by_hexdump.txt
0000000 0a 09 d7 93 d7 99 d7 a8 d7 95 d7 aa 20 d7 9c d7
0000020 a9 d7 95 d7 aa d7 a4 d7 99 d7 9d 20 20 d7 91 d7
0000040 aa d7 9c 20 d7 90 d7 91 d7 99 d7 91 20 2d 20 d7
0000060 94 d7 95 d7 9e d7 9c d7 a1 0a
0000072
ubuntu@ip-10-126-21-104:~$ file -i homeless-title-fromwireshark_followed_by_hexdump.txt
homeless-title-fromwireshark_followed_by_hexdump.txt: text/plain; charset=utf-8

文件是UTF-8,我已经通过打开记事本(windows7),输入希伯来语字符ד,然后保存文件来验证这一点。其结果如下:

ubuntu@ip-10-126-21-104:~$ od -t x1 test_from_notepad_utf8_daled.txt
0000000 ef bb bf d7 93
0000005
ubuntu@ip-10-126-21-104:~$ file -i test_from_notepad_utf8_daled.txt
test_from_notepad_utf8_daled.txt: text/plain; charset=utf-8

其中,ef bb bf是以utf-8形式编码的BOM,而d7 93正是出现在0a 09之后的原始流中的字节序列(新行,ascii中的制表符)。

这里的问题是,通过unicode代码页,ד应该被编码为05 D3,那么utf-8编码为什么以及如何变成d7 93呢?

二进制中的d7 9311010111 10010011,而
二进制中的05 D300000101 11010011

我似乎找不到对这些编码有意义的正确转换,(据我所知)这些编码表示相同的Unicode实体,即"HEBREW LETTER DALET"

谢谢,
格言

Unicode定义了(除其他外)一堆"代码点",并为每个代码点提供一个数值。HEBREW LETTER DALET的值为U+05D3或0x05D3。但这只是一个数字,并不能告诉你如何在文件/内存中"编码"代码点(即实际比特集)。。。UTF-8(以及UTF-16、UTF-32和各种其他方案)告诉您如何做到这一点。

实际上,有一种公式化的方法可以将Unicode代码点翻译成UTF-8字符(但这是一个完全不同的SO问题)。结果表明,在UTF-8中,HEBREW LETTER DALET被编码为0xD7 0x93。顺便说一句,如果你找到一个允许你保存为UTF-32或UCS-4的文本编辑器,你会发现(除了一个非常大的文件)你用十六进制编辑器看到的字节应该与Unicode规范中的代码点匹配。

这个页面可能会提供一些关于该字符的一些表示的额外信息。

为了更好地介绍Unicode,我建议Joel Spolsky的《每个软件开发人员都必须绝对、积极地了解Unicode和字符集的绝对最小值》(没有借口!)。

Unicode代码点U+0000..U+007F以UTF-8编码为单字节0x00..0x7F.

Unicode代码点u+0080.u+07FF(包括HEBREW LETTER DALET u+05D3)以UTF-8编码为两个字节。这些二进制值可以分为一组5位和一组6位,如xxxxx-yyyyy。UTF-8表示的第一个字节具有比特模式110xxxxx;第二个具有位模式10yyyyy。

0x05D3 = 0000 0101 1101 0011 

0x05D3的最后6位是010011;前缀为10,表示1001 0011或0x93。前面的5个比特是10111;前缀为110,给出1101 0111或0xD7。

因此,U+05D3的UTF-8编码为0xD7 0x93。

Unicode代码点U+0800以上有更多规则,UTF-8表示需要3或4个字节(但不是更多)。连续字节始终具有10yyyyy位模式。第一字节具有比特模式1110xxxx(3字节值)和11110xxx(4字节值)。有许多字节值不能以有效的UTF-8格式出现;它们是0xC0、0xC1和0xF5..0xFF.

Legacy代码页定义了一组字符及其到字节序列的映射。Unicode分离了字符集编码的概念。

因此,Unicode字符集是代码点的列表。每个代码点都被分配了一个唯一的值作为标识符——ד是U+05D3。

编码-Unicode转换格式-描述了如何将每个编码为单元的序列。

UTF-8使用1个八位字节的代码单元,代码点编码为1到4个字节的序列。该算法在RFC 3629中进行了描述。

UTF-16也有类似的过程,它使用2个八位字节的代码单元——每个代码点是两个或四个字节。对于UTF-32,除了将每个值都设为4字节长之外,没有什么可做的。这些编码可以是大端序或小端序形式,因此U+05D3在UTF-32中可能是00 00 05 D3D3 05 00 00。BOM通常用于判断正在使用哪种编码,以及如果数据的编码不明确,则字节序是什么。

还有UTF-7,但我从未在野外见过它

最新更新