為什麼會存在亂碼?什麼是編解碼?為什麼會有這麼多字符集?

2020-10-15 三太子敖丙

前言

亂碼這個東西相信大家都遇到過,今天我的女朋友三歪就火急火燎的上來找我:「親愛的,我的idea怎麼輸出亂碼了?」

我一頓操作就給他搞好了,但是三歪不愧是蘑菇街我的女朋友,好奇心跟我是一樣樣的,隨我。

那為什麼會出現亂碼呢?

什麼是編碼,什麼是解碼?

什麼是字符碼,什麼是字符集?

為什麼要有 Unicode ?UTF-8 和 GBK 又有什麼不同呢?

三歪坐在我的腿上對我撒嬌似的說出這一連串的問題,我這個人寵粉但是更寵女朋友,所以就有了這篇文章。

為什麼會出現亂碼

我們知道計算機裡存儲的只會是 0 和 1 組成的字節流,而僅是數字滿足不了我們的需求,我們還需要文本的處理等等,但是計算機只認識數字,所以我們需要告訴計算機什麼數字代表什麼字符

比如我指定 0000 代表 A,0001 代表 B 這樣計算機就知道了,所以我要把 AB 這兩個字符存入計算機的話,實際存儲的就是0000 0001其實就等於把每個字符定製一個唯一的編碼

但是這是我的指定,不同的人想法是不同的,比如小明就喜歡 1000 表示 A ,1111 表示 B,那小明的計算機按照他指定的編碼方式存儲,就是 1000 1111,之後傳輸給我的計算機,我拿到1000 1111,按照我的編碼解出來可能就是 %& 了,這就亂碼了。

所以亂碼的本質就是編碼和解碼實現沒對應上

有些同學可能對編碼和解碼的概念不太熟悉,我來解釋一下:

  • 編碼:其實就是將字符按照一定的格式轉換成字節流的過程。
  • 解碼:就是將字節流解析成字符。

可以看到隨意編碼的就會產生各自的計算機都無法正確解析的情況,所以需要有一個標準,大家都按那個標準來指定字符和數字的對應關係。

標準字符編碼

美國國家標準協會 ANSI 就制定了一個標準,即美國信息交換標準代碼(ASCII),規定了常用字符集的集合和對應的數字編號,例如 65 表示 A。

ASCII 實際上是 7 位編碼,用二進位代碼表示就是 0000000~1111111,不過 1 個字節是 8 位,所以一般都用 8 位來存儲。可以看到 ASCII 代表了 128 個字符,這其實是傾美國的編碼,你看同樣講英文的英國,ASCII 上都沒英鎊的標記。

還有人家的韓文,日文等等,更別說咱們中文了。

1 個字節最多只能表示 256 個字符,所以對我們來說不夠用,因此需要擴展,像 GB2312 就是我們國家標準總局發布的《信息交換用漢字編碼字符集》,後來又發布了 GBK ,這個 K 就是擴展的意思,在 GB2312 的基礎上又添加了很多比如繁體字等字符。

所以說等於每個國家都有自己的標準,因為語言都是不同的,各字符集的不同就導致計算機之間文檔的交流非常困難,因此大家又開始了一波標準化。

像美國的 ANSI 組織制定了 ANSI 標準字符編碼,其實就是制定平臺默認的編碼,比如中國的作業系統就用 GBK ,如果是美國就用 ASCII,作業系統會預裝這些標準字符集。

不過這只能解決一份文檔一份字符編碼的情況,假設我文檔裡面有日語、法語、德語、俄語、中文,你說怎麼辦?

Unicode

所以又搞了個 Unicode,又稱統一碼、萬國碼、單一碼

Unicode 字符集涵蓋了目前人類使用的所有字符,並為每個字符進行統一編號,分配唯一的字符碼,你看這種事情總得有人做,不然就沒法統一。

這裡有幾個術語我解釋一下,讓大夥更加清晰一些。

  • 字符:其實就像英文字母,或者我們的中文都叫字符
  • 字符集:那就是字符和編號對應的集合
  • 字符碼:就是字符集裡面字符對應的數字,或者說編號,比如在 ASCII 字符集裡面, A 的字符碼是 65
  • 字符編碼:就是按照字符集中字符和數字的映射關係,轉化成字節流的實現

對於 Unicode 而言有一點和之前的編碼不太一樣,它將字符集和編碼實現解耦了。

之前的編碼比如 ASCII 編碼、GBK 編碼等等,它們的字符集和編碼實現是綁死的,你可以理解成以前的編碼其實就是查表,有一個固定的表格裡面存儲這字符和對應固定的二進位,比如 A 對應的編號是 65,其二進位序列就是 01000001。

而 Unicode 不一樣,它將字符集和字符編碼實現分開了,比如 A 對應的編號是 65,但是對應的二進位序列就不一定了,得看具體的字符編碼,如果是 UTF-8 編碼,則是 01000001,如果是 UTF-16 編碼(大端),則是 00000000 01000001

這其實也是為什麼我們現在常用 UTF-8 而不是 UTF-16 的原因,可以看到 UTF-16 編碼存儲效率較低,最少使用兩個字節,並且像 C 語言的很多函數都會將 0x00 字節作為字符串的停止符來解析,所以才搞了個 UTF-8,其使用 1~4 字節為每個字符編碼,是變長的,具體如何編碼的我就不說了,隨便查一下就有。

最後

至此我們已經清晰了亂碼的根源,也知曉了為什麼會有那麼多字符編碼的出現,畢竟語言多,一開始出了個 ASCII,但是對於其他國家來說不夠用,於是都各自進行了擴展。

而編碼多了各個國家之間難以做到統一,不易兼容,所以後來國際組織制定搞了個 Unicode 字符集,對所有字符做了統一的編排,並且為了使得編碼更加靈活把字符集和編碼實現分開來。

對了,為什麼英文都不會出現亂碼就是因為絕大部分的字符集都是基於 ASCII 擴展的,所以都兼容 ASCII 。

本期就是應該算是一期比較有意思的科普系列,但是還是渴求你的點讚哈哈。

絮叨

敖丙把自己的面試文章整理成了一本電子書,共 1630頁!

乾貨滿滿,字字精髓。目錄如下,還有我複習時總結的面試題以及簡歷模板,現在免費送給大家。

我是敖丙,你知道的越多,你不知道的越多,感謝各位人才的:點讚收藏評論,我們下期見!


文章持續更新,回復【資料】有我準備的一線大廠面試資料和簡歷模板,,有大廠面試完整考點。

相關焦點

  • 字符編碼和字符集的簡單介紹
    各位小夥伴們大家好,在之前的文章中,小編介紹了java之字符緩衝輸入流,BufferedReader的簡單介紹,這次小編要介紹的是字符編碼還有字符集。反之,將存儲在計算機中的二進位按照某種規則解析出來,稱為解碼。編碼:能看懂的字符—>看不懂的字節解碼:看不懂的字節—>能看懂的字符編碼和解碼都有不同的規則即字符集或者編碼表,比如按A規則存儲,再按照A的存儲規則解析,就可以顯示正確的文本符號。反之,按照A規則存儲,B規則解析,就會導致亂碼現象。
  • 全網最全面、全詳細的編碼、解碼知識
    溫馨提示: 本文大約5097字,閱讀完大概需要3-5分鐘,希望您能耐心看完,倘若你對該知識點已經比較熟悉,你可以直接跳轉到你感興趣的地方,希望閱讀本文能夠對您有所幫助,如果閱讀過程中有什麼好的建議、看法,歡迎在文章下方留言或者私信我,您的意見對我非常寶貴,再次感謝你閱讀本文。
  • 從此再也不怕爬蟲「亂碼」問題!
    亂碼問題的出現就以爬取 51job 網站舉例,講講為何會出現「亂碼」問題,如何解決它以及其背後的機制。代碼示例:import requestsurl = "http://search.51job.com"res = requests.get(url)print(res.text)顯示結果:列印 res.text 時,發現了什麼?中文亂碼!!!不過發現,網頁的字符集類型採用的是 GBK 編碼格式。
  • 編碼解碼是什麼意思?URL 如何編碼解碼?為什麼要編碼?
    編碼解碼是什麼?編碼是信息從一種形式或格式轉換為另一種形式的過程,也稱為計算機程式語言的代碼簡稱編碼。用預先規定的方法將文字、數字或其它對象編成數碼,或將信息、數據轉換成規定的電脈衝信號。編碼在電子計算機、電視、遙控和通訊等方面廣泛使用。編碼是信息從一種形式或格式轉換為另一種形式的過程。解碼,是編碼的逆過程。
  • 深入理解 Java 亂碼問題
    亂碼問題說難不難,一句話解決,編碼和解碼採用相同的 charset (字符集)。System.out.println(a); String b = "\u261d"; System.out.println(b);// ☝ String ding = "\u4E00"; System.out.println(ding);// 一}java 中字符串與 Unicode 有什麼關係呢
  • 6 字符集簡介以及更改網頁字符集
    meta這個英文單詞就表示「元」,「元」有「基礎的、最小的」意思,所以<meta>標籤就是元標籤,表示網頁的最基礎的配置。<meta charset="UTF-8">這行代碼中,charset這個單詞,其中的char就是「字符」,set表示集合,所以sharset就表示「字符集」。這裡的"UTF-8"就是一種字符集。
  • 6 字符集簡介以及更改網頁字符集
    meta這個英文單詞就表示「元」,「元」有「基礎的、最小的」意思,所以<meta>標籤就是元標籤,表示網頁的最基礎的配置。否則會出現亂碼。注意:我們之前安裝的live server這個插件,由於功能所限,是不支持gb2312(gbk)字符集的,它只支持UTF-8這個字符集。
  • 再見亂碼:5分鐘讀懂MySQL字符集設置
    一、內容概述在MySQL的使用過程中,了解字符集、字符序的概念,以及不同設置對數據存儲、比較的影響非常重要。不少同學在日常工作中遇到的「亂碼」問題,很有可能就是因為對字符集與字符序的理解不到位、設置錯誤造成的。
  • 關於Apache默認編碼錯誤,導致網站亂碼的解決方案
    最近經常有客戶反饋在使用LAMP/WAMP時,遇到這樣的編碼錯誤問題:A網站程序編碼UTF-8編碼安裝成功,運行成功。B網站程序編gb2312也要安裝在同一伺服器上。這樣就出現問題了,Apache默認編碼UTF-8在解析A網站的時候沒有任何問題,當運行B網站時出現的」蝌蚪文」亂碼問題。
  • Python進階乾貨:「中文編碼亂碼」:案例及解決方法
    在初次編寫代碼的過程中,由於不太了解編碼形式,習慣性輸入中文,得到的結果便是亂碼、無法執行,經常拋出編碼轉換的異常。從128 到255這一頁的字符集被稱」擴展字符集「。中國人們得到計算機時,已經沒有可以利用的字節狀態來表示漢字,況且常用漢字太多了。於是完善了「擴展字符集」。
  • Content-Disposition 亂碼問題記錄
    開工後一切順利,到保存文件這一步卡殼了,為什麼下載的文件是亂碼?效果如下:而自己手動通過瀏覽器下載的文件名卻是:1123三年級【語文(統編版)】語文園地六-3學習任務單.docx。代碼其實很簡單:import requests, cgifile_url = "https://cache.bdschool.cn/index.php?
  • Oracle實例解析:編碼與字符集
    Oracle中的編碼與字符集  (1)為什麼需要兩個字符集?  Oracle中有兩個字符集:資料庫字符集和國家字符集。  為什麼要有兩個字符集?如果我知道只需要英文,設置資料庫字符集=US7ASCII,如果我知道只需要西歐字符,設置資料庫字符集=WE8MSWIN1252或者WE8ISO89859P1,或者乾脆就用AL32UTF8。你看,我只需要設定「資料庫字符集」,那麼「國家字符集」有什麼必要呢?
  • 結合實例學習|字符編碼和解碼
    什麼是編碼和解碼如果要讓計算機來按照人類的意願進行工作,則必須把人類所使用的這些字符集轉換為計算機所能理解的二進位碼,這個過程就是編碼,他的逆過程稱為解碼。因為計算機只能處理數字,如果要處理文本,就必須先把文本轉換為數字才能處理。所以才要有編碼的存在。
  • 快吧遊戲盒為什麼字體亂碼
    為什麼快吧遊戲盒全是亂碼?很多玩家都下載過快吧遊戲盒,那麼為什麼快吧遊戲盒全是亂碼呢?下面,小編就給大家帶來快吧遊戲盒全是亂碼的解決方法,希望對小夥伴們有所幫助。
  • 視頻編解碼學習分享
    目錄視頻為什麼要編解碼視頻是否可以壓縮編解碼實現原理編解碼標準和國際組織視頻文件封裝(容器)視頻質量評價體系1.為什麼視頻要編解碼?由於人類視覺系統的先天特性,原始圖像中有一些數據是人眼感知不到的,在圖像壓縮過程中可以去掉,在圖像恢復後不會影響圖像的主觀質量,這部分數據就是視覺冗餘。例如,人類視覺的一般分辨能力為2的6次方(64)灰度等級,而一般的圖像的量化採用的是2的8次方(256)灰度等級,即存在視覺冗餘。
  • Python能幹什麼?為什麼會這麼火
    Python是一門非常不錯的程式語言,也是目前非常具有發展前景的學科,可以從事的工作崗位有很多,薪資待遇也很高,成為了大家進入IT行業的首要選擇。那麼Python能幹什麼?為什麼會這麼火?那麼Python能幹什麼呢?
  • 解決亂碼問題可能並不麻煩
    由於之前就知道String中的轉換方式,還有一些工具類,因此今天就好好的整理一下java中jdk提供的幾種轉換方式,希望對你有幫助。一、編碼轉換原理1、為什麼需要編碼我們知道計算機存儲信息的最小單位是一個字節8位,能夠表示256個字符。這對於早起的英文來說足夠了。即使是加上一些常見符號也足夠。
  • python字符的編碼與解碼
    不同的國家有不同的字母,因此,哪怕它們都使用256個符號的編碼方式,代表的字母卻不一樣。比如,130在法語編碼中代表了é,在希伯來語編碼中卻代表了字母Gimel (),在俄語編碼中又會代表另一個符號。但是不管怎樣,所有這些編碼方式中,0--127表示的符號是一樣的,不一樣的只是128--255的這一段 。
  • 什麼是後門?為什麼會存在後門?
    什麼是後門?為什麼會存在後門?
  • 孫儷為什麼會這麼成功?原來是經歷了這麼多!
    也是由於他父母親的緣故,孫儷甚至表示有可能做「不婚主義者」。但是後來遇到鄧超,一切都不一樣了。有人問到,孫儷為什麼會這麼成功,這是跟她自己的努力分不開的,就讓小編給你們分析一下吧!該劇一播出,就引起了廣大網友的認可,孫儷在劇中從一個不諳世事的單純少女到一個善於謀權的深宮婦人的轉變飾演的特別好,孫儷在拍攝《甄嬛傳》的時候,因為臺詞具多,所以倍的演員都有時間休息,但是她沒有,就連吃飯聚餐也都是提前走在背臺詞。她的這種對待劇本認真的態度造就了如此繪聲繪色的甄嬛,也造就了她現在的成功。