日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

字符编码总结

發布時間:2023/12/9 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字符编码总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

字符編碼精華總結

文件或字符串亂碼相信大家都沒少遇到, 今天主要就來搞清楚字符串的編碼到底是怎 么一回事.

首先, 我們放把自己置空, 假設現在從來沒有字符編碼, 剛有一臺計算機產生, 讓我 們來設計一套方案, 目標是讓在計算機屏幕上看到我們平時所書寫的字符. 你會怎么 做?

1?編碼的本質

詳細的思考過程, 不再詳述, 只做大概的說明如下:

  • 選定?Character Set

首先要確定「我們平時所書寫的字符」, 到底都包括哪些字符, 也就是說, 要確定我 們到底要對哪些字符進行處理. 這里選定的字符集合叫做 Character Set 又叫 Character Repertoire.

  • 規定?Coded Character Set

對于已經選定的 Character Set, 我們需要給他們進行編號, 每個字符給一個編號, 也就是字符集合到一個整數集合的映射. 這個映射就叫做 Coded Character Set, 又叫 CCS.

  • 實現?Character Encoding

前兩步所做的?選定?和?規定?操作都是純數學或純邏輯上的, 跟計算機仍沒任何 聯系. 在這一步, 就需要將之前規定好的編號給弄進計算機中. 因為編號已經是數字 了, 數字存儲為二進制沒什么問題. 這里只有一個問題需要注意:?存儲編號的時候 使用多少字節??比如說, 某字符已經在第二步規定好了編號1, 在內存中存儲的時候, 是使用0x01?還是使用?0x00 01??

以大家熟知的ASCII字符集和編碼做為示例, 流程圖如下:

?

2?各種使用中的編碼

如上節所述, 編碼的本質, 就是把字符進行映射, 然后將映射后的數值進行存儲.

盡管各種編碼格式在歷史上層出不窮, 但上面的本質始終不變. 各編碼格式的區別在 于:

  • 對于所選定的字符集的不同. (ASCII, GBK, Big5, Unicode)
  • 對于選定的字符集進行編號時的不同. (即便有些向下兼容的編碼, 仍會有些字符編碼不一樣)
  • 對于編號進行計算機存儲時使用字節數的不同. (UTF-8, UTF-16, UTF-32)
  • 各編碼在上面各種情況下的詳細區別示例, 大家可以參看Wikipedia和文末的參考鏈 接, 這里不再贅述.

    3?Python中的編碼

    對應到大家平時的使用上, 第一步基本上我們做不了太多的選擇, 主要是第二步和第三步.

    第二步到第三步的編碼, 在編程里對應的就是?Encode?過程;

    第三步到第二步的解碼, 在編程里對應的就是?Decode?過程.

    關于Python字節流和Unicode對象之間轉換的詳細示例, 可參考Python編碼和Unicode

    ?

    UTF-8Unicode的關系

    看完上面兩個概念解釋,那么解釋UTF-8和Unicode的關系就比較簡單了。Unicode就是上文中提到的編碼字符集,而UTF-8就是字符編碼,即Unicode規則字庫的一種實現形式。隨著互聯網的發展,對同一字庫集的要求越來越迫切,Unicode標準也就自然而然的出現。它幾乎涵蓋了各個國家語言可能出現的符號和文字,并將為他們編號。詳見:Unicode on Wikipedia。Unicode的編號從0000開始一直到10FFFF共分為16個Plane,每個Plane中有65536個字符。而UTF-8則只實現了第一個Plane,可見UTF-8雖然是一個當今接受度最廣的字符集編碼,但是它并沒有涵蓋整個Unicode的字庫,這也造成了它在某些場景下對于特殊字符的處理困難(下文會有提到)。

    ?

    3.Unicode

    正如上一節所說,世界上存在著多種編碼方式,同一個二進制數字可以被解釋成不同的符號。因此,要想打開一個文本文件,就必須知道它的編碼方式,否則用錯誤的編碼方式解讀,就會出現亂碼。為什么電子郵件常常出現亂碼?就是因為發信人和收信人使用的編碼方式不一樣。

    可以想象,如果有一種編碼,將世界上所有的符號都納入其中。每一個符號都給予一個獨一無二的編碼,那么亂碼問題就會消失。這就是Unicode,就像它的名字都表示的,這是一種所有符號的編碼。

    Unicode當然是一個很大的集合,現在的規模可以容納100多萬個符號。每個符號的編碼都不一樣,比如,U+0639表示阿拉伯字母Ain,U+0041表示英語的大寫字母A,U+4E25表示漢字"嚴"。具體的符號對應表,可以查詢unicode.org,或者專門的漢字對應表。

    4. Unicode的問題

    需要注意的是,Unicode只是一個符號集,它只規定了符號的二進制代碼,卻沒有規定這個二進制代碼應該如何存儲。

    比如,漢字"嚴"的unicode是十六進制數4E25,轉換成二進制數足足有15位(100111000100101),也就是說這個符號的表示至少需要2個字節。表示其他更大的符號,可能需要3個字節或者4個字節,甚至更多。

    這里就有兩個嚴重的問題,第一個問題是,如何才能區別Unicode和ASCII?計算機怎么知道三個字節表示一個符號,而不是分別表示三個符號呢?第二個問題是,我們已經知道,英文字母只用一個字節表示就夠了,如果Unicode統一規定,每個符號用三個或四個字節表示,那么每個英文字母前都必然有二到三個字節是0,這對于存儲來說是極大的浪費,文本文件的大小會因此大出二三倍,這是無法接受的。

    它們造成的結果是:1)出現了Unicode的多種存儲方式,也就是說有許多種不同的二進制格式,可以用來表示Unicode。2)Unicode在很長一段時間內無法推廣,直到互聯網的出現。

    5.UTF-8

    互聯網的普及,強烈要求出現一種統一的編碼方式。UTF-8就是在互聯網上使用最廣的一種Unicode的實現方式。其他實現方式還包括UTF-16(字符用兩個字節或四個字節表示)和UTF-32(字符用四個字節表示),不過在互聯網上基本不用。重復一遍,這里的關系是,UTF-8是Unicode的實現方式之一。

    UTF-8最大的一個特點,就是它是一種變長的編碼方式。它可以使用1~4個字節表示一個符號,根據不同的符號而變化字節長度。

    UTF-8的編碼規則很簡單,只有二條:

    1)對于單字節的符號,字節的第一位設為0,后面7位為這個符號的unicode碼。因此對于英語字母,UTF-8編碼和ASCII碼是相同的。

    2)對于n字節的符號(n>1),第一個字節的前n位都設為1,第n+1位設為0,后面字節的前兩位一律設為10。剩下的沒有提及的二進制位,全部為這個符號的unicode碼。

    ?

    UTF-8字節流切片的問題

    因為一個UTF-8編碼串是一個字節列表,len( )和切片操作無法正常工作。首先用我們之前用的字符串。

    1

    [?97?] [?98?] [?99?] [?226?] [?128?] [?147?]?=?"abc–"

    接下來做以下的:

    1

    2

    3

    >>> my_utf8?=?"abc–"

    >>>?print?len(my_utf8)

    6

    神馬?它看起來是4個字符,但是len的結果說是6。因為len計算的是字節數而不是字符數。

    1

    2

    >>>?print?repr(my_utf8)

    'abc\xe2\x80\x93'

    現在我們來切分這個字符串。

    1

    2

    >>> my_utf8[-1]?# Get the last char

    '\x93'

    我去,切分結果是最后一字節,不是最后一個字符。

    為了正確的切分UTF-8,你最好是解碼字節流創建一個Unicode對象。然后就能安全的操作和計數了。

    1

    2

    3

    4

    5

    6

    7

    >>> my_unicode?=?my_utf8.decode("utf-8")

    >>>?print?repr(my_unicode)

    u'abc\u2013'

    >>>?print?len(my_unicode)

    4

    >>>?print?my_unicode[-1]

    引子:bytes/str之別

    Python 3最重要的新特性大概要算是對文本和二進制數據作了更為清晰的區分。文本總是Unicode,由str類型表示,二進制數據則由bytes類型表示。Python 3不會以任意隱式的方式混用str和bytes,正是這使得兩者的區分特別清晰。你不能拼接字符串和字節包,也無法在字節包里搜索字符串(反之亦然),也不能將字符串傳入參數為字節包的函數(反之亦然)。這是件好事。

    不管怎樣,字符串和字節包之間的界線是必然的,下面的圖解非常重要,務請牢記于心:

    ?

    字符串可以編碼成字節包,而字節包可以解碼成字符串。

    這個問題要這么來看:字符串是文本的抽象表示。字符串由字符組成,字符則是與任何特定二進制表示無關的抽象實體。在操作字符串時,我們生活在幸福的無知之中。我們可以對字符串進行分割和分片,可以拼接和搜索字符串。我們并不關心它們內部是怎么表示的,字符串里的每個字符要用幾個字節保存。只有在將字符串編碼成字節包(例如,為了在信道上發送它們)或從字節包解碼字符串(反向操作)時,我們才會開始關注這點。

    ?

    復習一下,我們有五個不可忽視的事實:

  • 程序中所有的輸入和輸出均為 byte
  • 世界上的文本需要比 256 更多的符號來表現
  • 你的程序必須處理 byte 和 unicode
  • byte 流中不會包含編碼信息
  • 指明的編碼有可能是錯誤的
  • ?

    Unicode 標準定義了多種方法來用 bytes 來表示成代碼點,被成為 encoding 。

    因此,Unicode計劃的首要任務就是把所有這些字符羅列出來,數個數。這就是Unicode的前半部分,通用字符集(Universal Character Set)。(真正談及Unicode時,不要把明文字符叫做“字符”,稱之為“碼點”(code points)。)【通用字符集】

    完成前面的工作后,你還得想出一種技術,以儲存全部對應的編碼文本字符。(用Unicode的話來說,編碼文本字符被稱作“碼值”(code values)。)【對字符集的編號】

    Unicode碼點、碼值、utf-8的關系

    對于Unicode來說,碼點相當于要編碼的字符集,碼值相當于對字符集的編號。而utf-8相當于編號在內存的存儲方式,即實現方式!

    ?

    ?

    ?

    參考文獻:

    http://www.lijigang.com/blog/2015/06/11/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81%E6%98%AF%E4%BB%80%E4%B9%88%E9%AC%BC/

    http://cenalulu.github.io/linux/character-encoding/

    http://blog.jobbole.com/50345/

    http://www.ituring.com.cn/article/61192

    http://pycoders-weekly-chinese.readthedocs.org/en/latest/issue5/unipain.html

    http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

    http://www.lijigang.com/blog/2015/06/11/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81%E6%98%AF%E4%BB%80%E4%B9%88%E9%AC%BC/

    ?

    ?

    ?

    ?

    轉載于:https://www.cnblogs.com/bitpeng/p/4771204.html

    總結

    以上是生活随笔為你收集整理的字符编码总结的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。