1 回答

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