国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Unicode,GBK和UTF8

前言

其實(shí)這是個(gè)老生常談的問題了,相信大家在第一次遇到Unicode編碼問題時(shí),都會(huì)在網(wǎng)上搜索一通,
找到幾個(gè)解釋,雖然有點(diǎn)雜亂,但還是感覺自己明白了些什么,然后就繼續(xù)忙別的事情.
而我之所以就這個(gè)問題專門寫一篇文章,原因是前兩天在與公司一位有十幾年工作經(jīng)驗(yàn)的JAVA程序員對(duì)接
API時(shí), 我問他返回的漢字是什么編碼的, 而他回答說"直接返回unicode". 一個(gè)如此有經(jīng)驗(yàn)的老程序員
對(duì)這種基本問題都不甚清楚, 因此我覺得還是有必要好好說一下這個(gè)問題的.

字符集

在介紹他們之間的區(qū)別時(shí), 我們先講下什么是Unicode. 簡單來說,Unicode是一個(gè)字符集(character set),
和ASCII一樣, 其作用是用一系列數(shù)字來表示字符(character), 這些數(shù)字有時(shí)也稱為碼點(diǎn)(code points).
在PC剛出來的時(shí)候,使用英文的幾位先驅(qū)認(rèn)為計(jì)算機(jī)需要表示的字符不多,26個(gè)英文字母加幾個(gè)回車換行等
特殊符號(hào),總共一百個(gè)字符頂天了,于是就有了ASCII. ASCII碼的大小為1個(gè)字節(jié),定義了128個(gè)字符,
分別表示為0-127. 比如字符'A'的碼點(diǎn)為65,回車符'\n'的碼點(diǎn)為10, 如下所示:

>>> ord('A')65>>> ord('0')48>>> ord('\n')10

當(dāng)然, 后來人們發(fā)現(xiàn), 世界上的字符遠(yuǎn)遠(yuǎn)不止128個(gè), 因此就需要一個(gè)新的字符集能表示世上所有的字符,
包括一個(gè)英文字符,一個(gè)漢字字符,一個(gè)象形文字等. 這個(gè)字符集就是Unicode. Unicode前向兼容了ASCII,
最多可以表示2^21(大概200萬)個(gè)字符,已經(jīng)足夠囊括當(dāng)今所有國家的文字, 如下所示:

>>> u'ソ'u'\u30bd'>>> u'龍'u'\u9f8d'>>> u'A'u'A'

目前unicode字符集表示完所有字符后還有剩余, 這些暫時(shí)用不到的部分通常用占位符FFFD表示.

字符編碼

有了字符集, 我們現(xiàn)在可以用任意數(shù)字來表示現(xiàn)實(shí)中的字符了. 但字符要保存在計(jì)算機(jī)中,必須要先經(jīng)過編碼.
有人問, 數(shù)字直接保存在內(nèi)存里不就行了嗎? 但是用多少個(gè)字節(jié)表示一個(gè)數(shù)字,以及每個(gè)字節(jié)的范圍這都是需要
預(yù)先約定的,這種約定就叫編碼. 假如我們有四個(gè)數(shù)字,1,2,3,4要保存在計(jì)算機(jī)里, 如果約定了utf-8編碼,
那么在內(nèi)存中的表示則如下:

00000001 00000010 00000011 00000100

其他的編碼規(guī)則有utf-16,gb2312,gbk等,具體的編碼規(guī)則不在本文的范圍內(nèi),想要深入了解的可以在網(wǎng)上查閱相關(guān)的文檔.
因此,我們可以看到,如果不按照約定的規(guī)則來解碼,就很有可能無法還原出原來的數(shù)據(jù),也就是我們經(jīng)常遇到的"亂碼".
下面以幾個(gè)例子來簡單說明:

>>> u'你好'u'\u4f60\u597d'>>> u'你好'.encode('utf8')'\xe4\xbd\xa0\xe5\xa5\xbd'>>> u'你好'.encode('gbk')'\xc4\xe3\xba\xc3'>>> u'你好'.encode('utf8').decode('gbk')u'\u6d63\u72b2\u30bd'>>> print u'你好'.encode('utf8').decode('gbk')浣犲ソ

如上面的代碼所示, "你好"兩個(gè)漢字字符的unicode分別為4f60和597d, utf-8編碼后占6個(gè)字節(jié), 而gbk編碼后占4個(gè)字節(jié).
如果用utf8編碼后錯(cuò)誤地用gbk來解碼, 就會(huì)得到3個(gè)unicode碼點(diǎn),分別表示字符,;而如果用gbk編碼后
錯(cuò)誤地用utf8來解碼, 則在解碼第二個(gè)字符時(shí)無法湊夠3個(gè)字節(jié), 因此會(huì)得到未知的結(jié)果, 甚至?xí)驗(yàn)閮?nèi)存越界訪問引起程序異常.

注: 本文的python代碼示例是在Linux Terminal下運(yùn)行的, 因此默認(rèn)為utf-8編碼, 如果你是在Windows cmd里運(yùn)行,
則通常默認(rèn)GBK編碼, 因此亂碼會(huì)在不同地方出現(xiàn):)

知道字符編解碼的用法之后,我們就可以解釋一下常見的一些亂碼由來了, 比如在Windows下,未初始化的棧會(huì)初始化為0xcc,
未初始化的堆內(nèi)存會(huì)初始化為0xcd, 可以看到前者為'燙'的gbk編碼,而后者正好為'屯'的gbk編碼, 如下所示:

>>> u'燙'u'\u70eb'>>> u'燙'.encode('gbk')'\xcc\xcc'>>> u'屯'u'\u5c6f'>>> u'屯'.encode('gbk')'\xcd\xcd'

前面也說過, unicode暫時(shí)沒用到碼點(diǎn)會(huì)用占位符FFFD來表示, 如果這個(gè)占位符被錯(cuò)誤解析, 就會(huì)被當(dāng)作有意義的內(nèi)容了:

>>> u'\uFFFD'.encode('utf8')'\xef\xbf\xbd'>>> u'錕斤拷'.encode('gbk')'\xef\xbf\xbd\xef\xbf\xbd'>>> print (u'\uFFFD'.encode('utf8')*2).decode('gbk')錕斤拷

可以看到,漢字"錕斤銬"(Unicode)的gbk編碼分別為\xef\xbf, \xbd\xef和\xbf\xbd, 正好是unicode碼FFFD的utf8編碼
的疊加, 因此如果平時(shí)遇到多個(gè)utf8編碼的Unicode占位符且不巧用了gbk的方式解碼,那就會(huì)看到熟悉的錕斤銬了.

其他

在Windows的Notepad.exe中, 保存文件的格式可以看到有如下幾種:

可剛剛不是說Unicode只是字符集嗎, 為什么上面顯示可以保存為Unicode"編碼"? 好吧, 其實(shí)這是Windows在命名上一個(gè)操蛋的
地方. 因?yàn)閃indows內(nèi)部使用UTF-16小端(UTF-16LE)作為默認(rèn)編碼,并且認(rèn)為這就是Unicode的標(biāo)準(zhǔn)編碼格式. 在Windows的世界中,
存在著ANSI字符串(在當(dāng)前系統(tǒng)代碼頁中, 不可拓展),以及Unicode字符串(內(nèi)部以UTF16-LE編碼保存). 因此notepad里所說的
Unicode大端,其實(shí)就是UTF16-BE.

這其實(shí)也不怪Windows, 因?yàn)檫@是在Unicode出現(xiàn)的早期設(shè)計(jì)的, 那時(shí)我們還沒意識(shí)到UCS-2的不足, 而且UTF-8還沒有被發(fā)明出來.
這也是為什么Windows對(duì)UTF8的支持如此之差的原因之一吧.

后記

說了這么多, 現(xiàn)在讓我們回到一開始的問題, 如果有人問你"Unicode,GBK和UTF-8有什么區(qū)別?", 我想你應(yīng)該知道該怎么回答了吧: Unicode是
一種字符集, 而GBK和UTF-8都是編碼, 因此Unicode和后兩者不是一類事物, 是無法進(jìn)行對(duì)比的.

博客地址:

歡迎交流,文章轉(zhuǎn)載請(qǐng)注明出處.

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
淺談 Python 2 中的編碼問題
Python2.7字符編碼詳解
SyntaxError: Non-ASCII character Python、Unicode和中文
編碼歪傳在Windows上做開發(fā)的同學(xué),一定要選擇“使用UTF-8無BOM格式”保存
[轉(zhuǎn)]Python的ASCII, GB2312, Unicode , UTF-8 - 海上...
編碼的秘密
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服