欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Unicode編碼大揭秘

 更新時(shí)間:2014年07月16日 11:48:04   投稿:junjie  
這篇文章主要介紹了Unicode編碼大揭秘,本文介紹了編碼的歷史,Unicode的出現(xiàn)原因等,需要的朋友可以參考下

如果你是一個(gè)生活在2003年的程序員,卻不了解字符、字符集、編碼和Unicode這些基礎(chǔ)知識(shí)。那你可要小心了,要是被我抓到你,我會(huì)讓你在潛水艇里剝六個(gè)月洋蔥來(lái)懲罰你。

這個(gè)邪惡的恐嚇是Joel Spolsky在十年前首次發(fā)出的。不幸的是,很多人認(rèn)為他只是在開(kāi)玩笑,因此,現(xiàn)在仍有許多人不能完全理解Unicode,以及Unicode、UTF-8、UTF-16之間的區(qū)別。這就是我寫這篇文章的原因。

言歸正傳,設(shè)想在一個(gè)晴朗的下午,你收到一封電子郵件,它來(lái)自一個(gè)你高中之后就失去聯(lián)系的朋友,并帶有一個(gè)txt格式(也稱為純文本格式)的附件。這個(gè)附件包含下面這樣一串二進(jìn)制bits:

復(fù)制代碼 代碼如下:

0100100001000101010011000100110001001111

Email的正文是空的,這使它更加神秘。在你啟動(dòng)常用的文本編輯器打開(kāi)這個(gè)附件之前,你有沒(méi)有想過(guò),文本編輯器是怎么將二進(jìn)制形式翻譯成字符的?這其中有兩個(gè)關(guān)鍵問(wèn)題:

1.字節(jié)是怎樣分組的?(例如1個(gè)字節(jié)的字符和2個(gè)字節(jié)的字符)

2.一個(gè)或多個(gè)字節(jié)是怎么映射到字符上的?

這些問(wèn)題的答案就在這篇文檔(Character Encoding)中,大致說(shuō)來(lái),編碼定義了兩件事:

1.字節(jié)是怎么分組的,如8 bits或16 bits一組,這也被稱作編碼單元。

2.編碼單元和字符之間的映射關(guān)系。例如,在ASCII碼中,十進(jìn)制65映射到字母A上

字符編碼和字符集之間有微小的區(qū)別。不過(guò)通常它和你無(wú)關(guān),除非你在設(shè)計(jì)一個(gè)底層的庫(kù)。

ASCII碼是上個(gè)世紀(jì)最流行的編碼體系之一,至少在西方是這樣。下圖顯示了ASCII碼中編碼單元是怎么映射到字符上的。

有一個(gè)即使在經(jīng)驗(yàn)豐富的程序員中也非常常見(jiàn)的誤解就是,純文本使用ASCII碼并且每個(gè)字符都是8 bits。

事實(shí)是,沒(méi)有這樣的「純文本」。如果在內(nèi)存或者硬盤中有一個(gè)你不知道編碼的字符串,那你就無(wú)法翻譯或者顯示它。這絕對(duì)沒(méi)有第二條路可選。

那么當(dāng)你剛剛收到的附件沒(méi)有指定編碼格式的時(shí)候,計(jì)算機(jī)會(huì)如何翻譯它呢?這是否意味著你就永遠(yuǎn)也讀不到失去聯(lián)系的老朋友想跟你說(shuō)的話了呢?在我們找到答案之前,我們首先回到那個(gè)年代————那個(gè)用錢能買到的最大硬盤是29MB的時(shí)代。

歷史回顧

很久以前,計(jì)算機(jī)制造商有自己的表示字符的方式。他們并不需要擔(dān)心如何和其它計(jì)算機(jī)交流,并提出了各自的方式來(lái)將字形渲染到屏幕上。隨著計(jì)算機(jī)越來(lái)越流行,廠商之間的競(jìng)爭(zhēng)更加激烈,在不同的計(jì)算機(jī)體系間轉(zhuǎn)換數(shù)據(jù)變得十分蛋疼,人們厭煩了這種自定義造成的混亂。

最終,計(jì)算機(jī)制造商一起制定了一個(gè)標(biāo)準(zhǔn)的方法來(lái)描述字符。他們定義使用一個(gè)字節(jié)的低7位來(lái)表示字符,并且制作了如上圖所示的對(duì)照表來(lái)映射七個(gè)比特的值到一個(gè)字符上。例如,字母A是65,c是99,~是126等等, ASCII碼就這樣誕生了。原始的ASCII標(biāo)準(zhǔn)定義了從0到127 的字符,這樣正好能用七個(gè)比特表示。不過(guò)好景不長(zhǎng)……


為什么選擇了7個(gè)比特而不是8個(gè)來(lái)表示一個(gè)字符呢?我并不關(guān)心。但是一個(gè)字節(jié)是8個(gè)比特,這意味著1個(gè)比特并沒(méi)有被使用,也就是從128到255的編碼并沒(méi)有被制定ASCII標(biāo)準(zhǔn)的人所規(guī)定,這些美國(guó)人對(duì)世界的其它地方一無(wú)所知甚至完全不關(guān)心。

其它國(guó)家的人趁這個(gè)機(jī)會(huì)開(kāi)始使用128到255范圍內(nèi)的編碼來(lái)表達(dá)自己語(yǔ)言中的字符。例如,144在阿拉伯人的ASCII碼中是گ,而在俄羅斯的ASCII碼中是ђ。即使在美國(guó),對(duì)于未使用區(qū)域也有各種各樣的利用。IBM PC就出現(xiàn)了“OEM 字體”或”擴(kuò)展ASCII碼”,為用戶提供漂亮的圖形文字來(lái)繪制文本框并支持一些歐洲字符,例如英鎊(£)符號(hào)。

再?gòu)?qiáng)調(diào)一遍,ASCII碼的問(wèn)題在于盡管所有人都在0-127號(hào)字符的使用上達(dá)成了一致,但對(duì)于128-255號(hào)字符卻有很多很多不同的解釋。你必須告訴計(jì)算機(jī)使用哪種風(fēng)格的ASCII碼才能正確顯示128-255號(hào)的字符。

這對(duì)于北美人和不列顛群島的人來(lái)說(shuō)不算什么問(wèn)題,因?yàn)闊o(wú)論使用哪種風(fēng)格的ASCII碼,拉丁字母的顯示都是一樣的。英國(guó)人還需要面對(duì)的問(wèn)題是原始的ASCII碼中不包含英鎊符號(hào),但是這個(gè)已經(jīng)無(wú)關(guān)緊要了。

與此同時(shí),在亞洲有更讓人頭疼的問(wèn)題。亞洲語(yǔ)言有更多的字符和字形需要被存儲(chǔ),一個(gè)字節(jié)已經(jīng)不夠用了。所以他們開(kāi)始使用兩個(gè)字節(jié)來(lái)存儲(chǔ)字符,這被稱作DBCS(雙字節(jié)編碼方案)。在DBCS中,字符串操作變得很蛋疼,你應(yīng)該怎么做str++或str–?

這些問(wèn)題成為了系統(tǒng)開(kāi)發(fā)者的噩夢(mèng)。例如,MS DOS必須支持所有風(fēng)格的ASCII碼,因?yàn)樗麄兿氚衍浖u到其他國(guó)家去。他們提出了「內(nèi)碼表」這一概念。例如,你需要告訴DOS(通過(guò)使用”chcp”命令)你想使用保加利亞語(yǔ)的內(nèi)碼表,它才能顯示保加利亞字母。內(nèi)碼表的更換會(huì)應(yīng)用到整個(gè)系統(tǒng)。這對(duì)使用多種語(yǔ)言工作的人來(lái)說(shuō)是一個(gè)問(wèn)題,因?yàn)樗麄儽仨氼l繁的在幾個(gè)內(nèi)碼表之間來(lái)回切換。

盡管內(nèi)碼表是一個(gè)好主意,但是它不是一個(gè)簡(jiǎn)潔的解決方案,它只是一個(gè)hack技術(shù)或者說(shuō)是簡(jiǎn)單的修正來(lái)讓編碼系統(tǒng)可以工作。

進(jìn)入U(xiǎn)nicode的世界

最終,美國(guó)人意識(shí)到他們應(yīng)該提出一種標(biāo)準(zhǔn)方案來(lái)展示世界上所有語(yǔ)言中的所有字符,以便緩解程序員的痛苦和避免字符編碼引發(fā)的第三次世界大戰(zhàn)。出于這個(gè)目的,Unicode誕生了。

Unicode背后的想法非常簡(jiǎn)單,然而卻被普遍的誤解了。Unicode就像一個(gè)電話本,標(biāo)記著字符和數(shù)字之間的映射關(guān)系。Joel稱之為「神奇數(shù)字」,因?yàn)樗鼈兛赡苁请S機(jī)指定的,而且不會(huì)給出任何解釋。官方術(shù)語(yǔ)是碼位(Code Point),總是用U+開(kāi)頭。理論上每種語(yǔ)言中的每種字符都被Unicode協(xié)會(huì)指定了一個(gè)神奇數(shù)字。例如希伯來(lái)文中的第一個(gè)字母א,是U+2135,字母A是U+0061。

Unicode并不涉及字符是怎么在字節(jié)中表示的,它僅僅指定了字符對(duì)應(yīng)的數(shù)字,僅此而已。

關(guān)于Unicode的其它誤解包括:Unicode支持的字符上限是65536個(gè),Unicode字符必須占兩個(gè)字節(jié)。告訴你這些的人應(yīng)該去換換腦子了。

記住,Unicode只是一個(gè)用來(lái)映射字符和數(shù)字的標(biāo)準(zhǔn)。它對(duì)支持字符的數(shù)量沒(méi)有限制,也不要求字符必須占兩個(gè)、三個(gè)或者其它任意數(shù)量的字節(jié)。

Unicode字符是怎樣被編碼成內(nèi)存中的字節(jié)這是另外的話題,它是被UTF(Unicode Transformation Formats)定義的。

Unicode編碼

兩個(gè)最流行的Unicode編碼方案是UTF-8和UTF-16。讓我們看看它們的細(xì)節(jié)。

UTF-8

UTF-8是一個(gè)非常驚艷的概念,它漂亮的實(shí)現(xiàn)了對(duì)ASCII碼的向后兼容,以保證Unicode可以被大眾接受。發(fā)明它的人至少應(yīng)該得個(gè)諾貝爾和平獎(jiǎng)。

在UTF-8中,0-127號(hào)的字符用1個(gè)字節(jié)來(lái)表示,使用和US-ASCII相同的編碼。這意味著1980年代寫的文檔用UTF-8打開(kāi)一點(diǎn)問(wèn)題都沒(méi)有。只有128號(hào)及以上的字符才用2個(gè),3個(gè)或者4個(gè)字節(jié)來(lái)表示。因此,UTF-8被稱作可變長(zhǎng)度編碼。

回到文章開(kāi)始的問(wèn)題,來(lái)自你老朋友的附件的字節(jié)流如下:

復(fù)制代碼 代碼如下:

0100100001000101010011000100110001001111

這個(gè)字節(jié)流在ASCII和UTF-8中表示相同的字符:HELLO

UTF-16

另一個(gè)流行的可變長(zhǎng)度編碼方案是UTF-16,它使用2個(gè)或者4個(gè)字節(jié)來(lái)存儲(chǔ)字符。然而,人們逐漸意識(shí)到UTF-16可能會(huì)浪費(fèi)存儲(chǔ)空間,但那是另一個(gè)話題了。

低字節(jié)序(Little Endian)和高字節(jié)序(Big Endian)

Endian讀作End-ian或者Indian。這個(gè)術(shù)語(yǔ)的起源可以追溯到格列佛游記。(小說(shuō)中,小人國(guó)為水煮蛋應(yīng)該從大的一端(Big-End)剝開(kāi)還是小的一端(Little-End)剝開(kāi)而爭(zhēng)論,爭(zhēng)論的雙方分別被稱為“大端派”和“小端派”。)

低字節(jié)序和高字節(jié)序只是一個(gè)關(guān)于在內(nèi)存中存儲(chǔ)和讀取一段字節(jié)(被稱作words)的約定。這意味著當(dāng)你讓計(jì)算機(jī)用UTF-16把字母A(占兩個(gè)字節(jié))存在內(nèi)存中時(shí),使用哪種字節(jié)序方案決定了你把第一個(gè)字節(jié)放在第二個(gè)字節(jié)的前面還是后面。這么說(shuō)有點(diǎn)不太容易懂,讓我們來(lái)看一個(gè)例子:當(dāng)你使用UTF-16存下來(lái)自你朋友的附件時(shí),在不同的系統(tǒng)中它的后半部分可能是這樣的:

00 68 00 65 00 6C 00 6C 00 6F(高字節(jié)序,高位字節(jié)被存在前面)

68 00 65 00 6C 00 6C 00 6F 00(低字節(jié)序,低位字節(jié)被存在前面)

字節(jié)序方案只是一個(gè)微處理器架構(gòu)設(shè)計(jì)者的偏好問(wèn)題,例如,Intel使用低字節(jié)序,Motorola使用高字節(jié)序。

字節(jié)順序標(biāo)記(BOM)

如果你經(jīng)常要在高低字節(jié)序的系統(tǒng)間轉(zhuǎn)換文檔,并且希望區(qū)分字節(jié)序,還有一種奇怪的約定,被稱作BOM。BOM是一個(gè)設(shè)計(jì)得很巧妙的字符,用來(lái)放在文檔的開(kāi)頭告訴閱讀器該文檔的字節(jié)序。在UTF-16中,它是通過(guò)在第一個(gè)字節(jié)放置FE FF來(lái)實(shí)現(xiàn)的。在不同字節(jié)序的文檔中,它會(huì)被顯示成FF FE或者FE FF,清楚的把這篇文檔的字節(jié)序告訴了解釋器。

BOM盡管很有用,但并不是很簡(jiǎn)潔,因?yàn)檫€有一個(gè)類似的概念,稱作「魔術(shù)字」(Magic Byte),很多年來(lái)一直被用來(lái)表明文件的格式。BOM和魔術(shù)字間的關(guān)系一直沒(méi)有被清楚的定義過(guò),因此有的解釋器會(huì)搞混它們。

恭喜你讀到這里,你一定是一個(gè)很有耐心的讀者。

還記得文章開(kāi)頭的問(wèn)題嗎,既然沒(méi)有「純文本」文件這回事,那你的文本編輯器和瀏覽器為什么每次都能正確的顯示內(nèi)容呢?答案是,那些軟件欺騙了你,這也是為什么那么多人對(duì)編碼一無(wú)所知。當(dāng)軟件不能確定編碼的時(shí)候,它會(huì)猜測(cè)。大部分時(shí)候,它會(huì)猜測(cè)是否是涵蓋了ASCII碼的UTF-8,還是ISO-8859-1,也有可能猜其他能想到的任意字符集。因?yàn)橛⑽闹惺褂玫睦∽帜副碓趲缀跛械淖址卸寄茱@示,包括UTF-8,所以即使編碼猜錯(cuò)了,英文字母看起來(lái)也是正確的。

但是,如果你在瀏覽網(wǎng)頁(yè)時(shí)看到�符號(hào),這意味著這個(gè)網(wǎng)頁(yè)的編碼不是你的瀏覽器猜測(cè)的那個(gè)。這時(shí)你可以點(diǎn)開(kāi)瀏覽器的查看——>字符編碼菜單來(lái)嘗試不同的編碼。

總結(jié)

如果你沒(méi)時(shí)間讀整篇文章或者你僅僅是略讀了一下前面的內(nèi)容。那請(qǐng)你確保你能理解下面的幾條:

這個(gè)世界上從來(lái)沒(méi)有純文本這回事,如果你想讀出一個(gè)字符串,你必須知道它的編碼。

Unicode是一個(gè)簡(jiǎn)單的標(biāo)準(zhǔn),用來(lái)把字符映射到數(shù)字上。Unicode協(xié)會(huì)的人會(huì)幫你處理所有幕后的問(wèn)題,包括為新字符指定編碼。

Unicode并不告訴你字符是怎么編碼成字節(jié)的。這是被編碼方案決定的,通過(guò)UTF來(lái)指定。

還有最重要的:

永遠(yuǎn)記得通過(guò)Content-Type或者meta charset標(biāo)簽來(lái)顯式指定你的文檔的編碼。這樣瀏覽器就不需要猜測(cè)你使用的編碼了,他們會(huì)準(zhǔn)確的使用你指定的編碼來(lái)渲染文檔。

相關(guān)文章

  • http請(qǐng)求405錯(cuò)誤方法不被允許的解決 (Method not allowed)

    http請(qǐng)求405錯(cuò)誤方法不被允許的解決 (Method not allowed)

    這篇文章主要介紹了http請(qǐng)求405錯(cuò)誤方法不被允許的解決 (Method not allowed),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • vs2019+cmake實(shí)現(xiàn)Linux遠(yuǎn)程開(kāi)發(fā)的方法步驟

    vs2019+cmake實(shí)現(xiàn)Linux遠(yuǎn)程開(kāi)發(fā)的方法步驟

    這篇文章主要介紹了vs2019+cmake實(shí)現(xiàn)Linux遠(yuǎn)程開(kāi)發(fā)的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • 教你給《羊了個(gè)羊》配置一套智能客服系統(tǒng)

    教你給《羊了個(gè)羊》配置一套智能客服系統(tǒng)

    這篇文章主要介紹了如何給《羊了個(gè)羊》配置一套智能客服系統(tǒng),通過(guò)微信小游戲接入智能客服的演示就完成了,希望能夠?qū)Ω嘈∮螒颉⑿〕绦蜷_(kāi)發(fā)團(tuán)隊(duì)有所幫助,需要的朋友可以參考下
    2022-09-09
  • 使用Visual Studio進(jìn)行文件差異比較的問(wèn)題小結(jié)

    使用Visual Studio進(jìn)行文件差異比較的問(wèn)題小結(jié)

    這篇文章主要介紹了使用Visual Studio進(jìn)行文件差異比較,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • 最新WebStorm2020.2注冊(cè)碼永久激活(激活到2089年)

    最新WebStorm2020.2注冊(cè)碼永久激活(激活到2089年)

    JetBrains旗下有多款編譯器工具(如:IntelliJ、WebStorm、PyCharm等)在各編程領(lǐng)域幾乎都占據(jù)了壟斷地位。今天給大家?guī)?lái)的是將WebStorm最新版激活至2089年
    2020-09-09
  • java asp分析各種搜索引擎的關(guān)鍵字,自動(dòng)識(shí)別url 中關(guān)鍵字的編碼

    java asp分析各種搜索引擎的關(guān)鍵字,自動(dòng)識(shí)別url 中關(guān)鍵字的編碼

    網(wǎng)上也有一些代碼,大部分都是通過(guò)輸入的關(guān)鍵字來(lái)識(shí)別編碼,并解碼。但是搜索引擎得到的referer來(lái)源地址上的關(guān)鍵字是通過(guò)URLencode編碼過(guò)的,而且各個(gè)網(wǎng)站的關(guān)鍵字Urlencode編碼都不一樣,gbk,utf-8,gb2312等等。
    2009-01-01
  • Eclipse插件安裝的八種方式總結(jié)

    Eclipse插件安裝的八種方式總結(jié)

    這篇文章主要給大家總結(jié)介紹了關(guān)于Eclipse插件安裝的八種方式,現(xiàn)在開(kāi)發(fā)java項(xiàng)目普遍使用idea了,但使用eclipse的也不少,如果要用的順手點(diǎn),還是需要一些優(yōu)化和相關(guān)插件支持的,需要的朋友可以參考下
    2023-10-10
  • antd通過(guò) filterDropdown 自定義按某天時(shí)間搜索功能

    antd通過(guò) filterDropdown 自定義按某天時(shí)間搜索功能

    這篇文章主要介紹了antd通過(guò) filterDropdown 自定義按某天時(shí)間搜索功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • 12個(gè)常用前端UI框架集合匯總

    12個(gè)常用前端UI框架集合匯總

    本文整理了一些比較流行的前端UI框架其中有VUE、bootstrap、jQuery等框架,,排名不分先后,僅供參考??砂凑枕?xiàng)目需求自行考慮
    2020-02-02
  • 關(guān)于Xmind免費(fèi)激活方法(推薦)

    關(guān)于Xmind免費(fèi)激活方法(推薦)

    這篇文章主要介紹了關(guān)于Xmind免費(fèi)激活方法,下載好之后需要打開(kāi)安裝路徑然后激活,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10

最新評(píng)論