2013-09-10 76 views
0

我對Unicode的十六進制表示感到困惑。 我有一個示例文件,其中包含一個數學整數符號字符。那就是U + 222B 如果我在vi中捕獲文件或編輯它,我會顯示一個整數符號。 該文件的十六進制轉儲顯示其十六進制內容是88e2 0aab關於unicode表示的困惑

在python中,我可以創建一個整數unicode字符並在我的終端和積分符號上打印p渲染。

>>> p=u'\u222b' 
>>> p 
u'\u222b' 
>>> print p 
∫ 

讓我困惑的是我可以打開一個帶有積分符號的文件,得到積分符號,但十六進制內容是不同的。

>>> c=open('mycharfile','r').read() 
>>> c 
'\xe2\x88\xab\n' 
>>> print c 
∫ 

一個是一個Unicode對象,一個是純字符串,但什麼是顯然是相同的字符兩個十六進制代碼之間的關係?我將如何手動將一個轉換爲另一個?

+1

'0x222b' = 8747是Unicode中與整數符號「∫」關聯的代碼點的整數值。當您將文本寫入文件或通過線路發送文件時,必須始終將其串行化爲位 - 通常,八位位組(字節)是此處的首選單位。 0xe2「,」0x88「,」0xab「(或二進制中的」0b11100010「,」0b10001000「,」0b10101011「)是UTF-8編碼(http://en.wikipedia.org/wiki/UTF- 8)的'0x222b'。順便說一句,第一個字節中的三個前導'1'告訴你這個碼點是用三個字節編碼的:UTF-8既是可變寬度也是'同步'。 – flow

+0

強制性:http://bit.ly/unipain – Daenyth

+0

這種微小的鏈接看起來很有前途。還有一點應該指出,Py3中的Unicode處理比以前在Py2中更加明智 - 在決定使用哪個Python版本時,這個因素應該大量權衡。令人遺憾的是,Py2和Py3之間存在着不合理的分歧,第三方庫支持滯後。 Py3的亮點在於舊的「ASCII字符串」消失了;你總是處理字節(編碼)或(Unicode)文本(解碼)的緩衝區。它只是改變了概念/命名的東西,但是編程很多都是關於概念和命名的。 – flow

回答

3

純字符串已使用UTF-8進行編碼,UTF-8是以字節表示Unicode代碼點的各種方法之一。 UTF-8是一種多字節編碼,它具有通常有用的特性,即它是ASCII的超集 - 同一字節以UTF-8或ASCII編碼任何ASCII字符。

在Python 2.x中,使用Unicode對象上的encode方法來編碼它,decodeunicode構造將其解碼:

>>> u'\u222b'.encode('utf8') 
'\xe2\x88\xab' 
>>> '\xe2\x88\xab'.decode('utf8') 
u'\u222b' 
>>> unicode('\xe2\x88\xab', 'utf8') 
u'\u222b' 

print,給定一個Unicode參數時,隱式地編碼它。在我的系統:

>>> sys.stdout.encoding 
'UTF-8' 

print的行爲更長的討論看到這個答案: Why does Python print unicode characters when the default encoding is ASCII?

Python 3中不同的方式處理事情有點;這些變化記錄在這裏: http://docs.python.org/3.0/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit

+2

必須閱讀:[絕對最低限度每個軟件開發人員絕對,肯定必須知道Unicode和字符集(無藉口!)](http://www.joelonsoftware.com/articles/Unicode.html)由Joel Spolsky。 – usr2564301

0

好吧,我有它。感謝您的答案。我想看看如何進行轉換,而不是使用Python轉換字符串。

這種轉換工作方式。

如果你有一個unicode字符,在我的例子中是一個整數符號。

八路轉儲產生

echo -n "∫"|od -x 
0000000 88e2 00ab 

每個十六進制對被顛倒,從而它的真正含義

e288ab00 

第一十六進制字符是E.高位意味着這是一個Unicode字符串和接下來的兩個位表示3個三字節(16位)來表示字符。 其餘十六進制數字的前兩位被丟棄(它們表示它們是unicode。)全比特流是

111000101000100010101011 

扔掉前4位和剩餘十六進制數字的前兩位

0010001000101011 

重新表達以十六進制此

222B 

它們你擁有了它!

+0

「高位表示這是一個Unicode字符串」並不完全正確。它模糊了使用非ASCII字符與UTF-8特定編碼細節之間的界限。更確切地說,高位意味着它是多字節編碼的一部分;在第一個0之前的前導1的數量告訴你編碼中的總字節數(在本例中爲3)。您的實際處理過程是正確的,但我建議您仔細閱讀與Jongware相關的Joel軟件文章。 Unicode和編碼是相關的概念,但不像這個措辭所暗示的那樣可以互換。 –