1 回答

TA貢獻(xiàn)1777條經(jīng)驗 獲得超3個贊
似乎 Python 不想接受某些字節(jié)序列作為有效的 UTF-8,而某些網(wǎng)站(https://mothereff.in/utf-8)接受它。其中一個肯定是錯的,對吧?讓我們來看看。
b'\xc2\xb7'Python 接受前兩個字節(jié) ( )。Python 不喜歡的第一件事是:\xed\xa0\x81\xed\xb1\x96,在那個網(wǎng)站上被解釋為 ??。
讓我們看一下\xed\xa0\x81\xed\xb1\x96二進(jìn)制格式:
11101101
10100000
10000001
11101101
10110001
10010110
RFC3629說 UTF-8 被解釋為:
Char. number range | UTF-8 octet sequence
(hexadecimal) | (binary)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
因此,有兩個三字節(jié)字符:
1110 1101 10 100000 10 000001 ? 1101100000000001,或 D801
1110 1101 10 110001 10 010110 ? 1101110001010110,或 DC56
性格D801是高級代理之一,DC56也是低級代理之一。
您可以在此處查看如何組合代理:
代理對表示代碼點 0x10000 + (H ? 0xD800) × 0x400
(L ? 0xDC00) 其中 H 和 L 分別是高和低代理的數(shù)值。
如果你把它們結(jié)合起來,你會得到:
0x10000 + (0xD801 - 0xD800) * 0x400 + (0xDC56 - 0xDC00) = 0x10456,也就是??
然而,高和低代理是為不適合 16 位的字符的 UTF-16 表示而設(shè)計的,這就是unicode.org關(guān)于在 UTF-8 中使用這種代理對的說法:
問:如何將 UTF-16 代理對轉(zhuǎn)換為<D800 DC00>UTF-8?作為一個 4 字節(jié)序列還是作為兩個單獨的 3 字節(jié)序列?
答:UTF-8 的定義要求補充字符(在 UTF-16 中使用代理對的那些)使用單個 4 字節(jié)序列進(jìn)行編碼。然而,在舊軟件中生成 3 字節(jié)序列對的做法很普遍,尤其是在引入 UTF-16 之前或在特定約束下與 UTF-16 環(huán)境互操作的軟件。這種編碼不符合定義的 UTF-8。有關(guān)此類非 UTF-8 數(shù)據(jù)格式的正式描述,請參見UTR #26:UTF-16:8 位 (CESU) 的兼容性編碼方案。使用 CESU-8 時,由于格式的相似性,必須非常小心不要將數(shù)據(jù)意外地視為 UTF-8。[自動對焦]
這里的關(guān)鍵點是“這樣的編碼不符合定義的 UTF-8”。所以,你的輸入實際上是一個無效的 UTF-8 序列,Python 拒絕了它。
要回答這個問題:
https://mothereff.in/utf-8忽略了 unicode.org 將其視為無效的指令。
Python 將其視為無效。
如果您想對其進(jìn)行解碼,即使它無效,您也可以編寫一個函數(shù)來完成我手動執(zhí)行的操作。
添加回答
舉報