徹底擺脫亂碼的困惑

這世上爲什麼要有亂碼這個東西...

先給大家出個思考題吧,一個漢字佔多少字節?是不是網上搜出的答案五花八門,那麼讀完本篇文章,我希望你至少可以準確知道這個問題的答案,我覺得就算是收穫

計算機是用 0 和 1 這種二進制形式,來表示一切信息的。所以它需要對所有的信息進行編碼,對整數、浮點數進行編碼,對字符串進行編碼,對聲音、圖片、視頻進行編碼。每一種編碼都可以深入研究來品味,比如人們發明出補碼來使計算機的減法變成加法,還有各種將聲音、圖片等看似不可能的媒體信息編碼成 0 和 1。一切都很美妙,唯獨字符編碼很討人厭,往往程序員們都不願意碰,因爲它實在是太亂了。

那今天就由我來幫你理一理。

一、什麼是編碼

這個問題很重要

編碼是把數據從一種形式轉換爲另外一種形式的過程,而解碼則是編碼的你過程。

注意,這裏可沒有說計算機喲,所以編碼是一個更大的概念,比如我們每個人都有名字,那你的名字就是你這個人的一種編碼。你還有身份證號,那你的身份證號又是你的一種編碼。別小看這個簡單的例子,它能解釋你經常混淆的兩個概念。

二、字符集與字符編碼

字符集是一個系統支持的所有抽象字符的集合,它是各種文字和符號的總稱,比如 ASCII 字符集、GBK 字符集,這就好比剛剛說的所有人這個集合。

字符編碼則是怎麼把字符集裏的這些字符一一用二進制表示的一個字典,或者說一個函數,比如 ASCll 字符編碼、GBK 字符編碼,這就好比剛剛說的名字表示法身份證號表示法

咦?ASCII 字符集對應的編碼方式是 ASCII 字符編碼,GBK 字符集對應的編碼方式是 GBK 字符編碼?沒錯,通常來說,字符集同時定義了一套同名的字符編碼規則。有人就有疑問了,那人這個字符集,不是可以用名字和身份證號兩種字符編碼麼?是的,字符也可以,比如 Unicode 字符集,就可以用 UTF-8、UTF-16 等多種字符編碼來表示。

還需要注意的一點是,在計算機的世界裏,不會有像名字表示法這樣,一個名字可能對應好多人的情況,所以名字表示法在字符編碼這裏,就不是一個好的字符編碼方式,自然也不會有人廣泛採用了。

三、字符編碼的起源 ASCII

世界上第一份字符集和編碼標準,顯然是由美國人起草的,就是大名鼎鼎的 ASCII,一共包含了 128 個字符以及對應的二進制,比如小寫字母 a 對應 01100001。這 128 個字符包括了可顯示的 26 個字母(大小寫)、10 個數字、標點符號以及特殊的控制符,也就是英語與西歐語言中常見的字符,這 128 個字符用一個字節(可表示 256 個字符)來表示綽綽有餘,所以當時只用了 7 位,還留了一個最高位當做奇偶校驗。不奇怪,英語國家的人覺得這真的足夠了,假如世界上所有人都用英語,那字符編碼真的超級簡潔,也就不會有什麼亂碼問題和這篇文章了。

每一種字符編碼最好的描述方式就是簡單粗暴的一個字典,或者說一張表,比如 ASCII,沒什麼可解釋的,它就是一張表。編碼就從右往左看,解碼就從左往右看。詳見附錄 ASCII。

四、字符編碼開始初步發展(歐洲)

EASCII:擴展的 ASCII

我們說 ASCII 發生於美國,因爲一開始只有美國有計算機,所以 ASCII 足夠了。可是隨着計算機的普及,西歐等國家首先開始使用(注意這時候還沒有中國)。西歐語言的字符雖然沒有中文這麼多,但有很多字符是 ASCII 表示不了的。於是他們就把 ASCII 擴充變成了 EASCII,這擴充的包括希臘字母、特殊的拉丁符號等。由於 ASCII 只佔了 7 位,所以 EASCII 把第 8 位利用起來,仍然是一個字節來表示,這時表示的字符個數是 256。

但 EASCII 並沒有成功,西歐國家以及各個 PC 廠商各自定義出了好多不同的編碼字符集,這時候你自然就能想到,一定有一個組織站出來統一這個混亂的局面,制定一個標準,這個組織就是國際標準化組織 ISO國際電工委員會 IEC

ISO-8859

這兩個組織制定了一系列的 8 位字符集標準,叫做 ISO-8859。請注意,這叫一系列,我們常說的 ISO-8859-1 纔是一個字符集標準,只是 ISO-8859 系列中的一個。之所以定一個系列,因爲那時候還想着用單字節來編碼,但除去 ASCII 佔有的 0x00~0x7F,就只剩下 0x80~0xFF 可以使用了,比如將ISO-8859-1,就是向下兼容 ASCII 的字符集標準,其編碼範圍是 0x00~0xFF,0x00~0x7F 之間完全和 ASCII 一致,0x80~0x9F 之間是控制字符,0xA0~0xFF 之間是文字符號。

各個國家的符號都容納進來顯然是不夠的,於是就分成了好多個版本,你是哪個國家的就用哪個。我們之所以經常提到 ISO-8859-1,是因爲它適用於西歐國家,而英國就是西歐國家。

以下是全部的 ISO-8859 系列

標準名稱 別名 適用範圍
ISO/IEC 8859-1 Latin-1 西歐語言
ISO/IEC 8859-2 Latin-2 中歐語言
ISO/IEC 8859-3 Latin-3 南歐語言。世界語也可用此字符集顯示。
ISO/IEC 8859-4 Latin-4 北歐語言
ISO/IEC 8859-5 Cyrillic 斯拉夫語言
ISO/IEC 8859-6 Arabic 阿拉伯語
ISO/IEC 8859-7 Greek 希臘語
ISO/IEC 8859-8 Hebrew 希伯來語(視覺順序)
ISO/IEC 8859-8-I Hebrew-I 希伯來語(邏輯順序)
ISO/IEC 8859-9 Latin-5 或 Turkish 它把 Latin-1 的冰島語字母換走,加入土耳其語字母
ISO/IEC 8859-10 Latin-6 或 Nordic 北日耳曼語支,用來代替 Latin-4
ISO/IEC 8859-11 Thai 泰語,從泰國的 TIS620 標準字集演化而來。
ISO/IEC 8859-13 Latin-7 或 Baltic Rim 波羅的語族
ISO/IEC 8859-14 Latin-8 或 Celtic 凱爾特語族
ISO/IEC 8859-15 Latin-9 西歐語言,加入 Latin-1 欠缺的芬蘭語字母和大寫法語重音字母,以及歐元(€)符號。
ISO/IEC 8859-16 Latin-10 東南歐語言。主要供羅馬尼亞語使用,並加入歐元符號。

我們看到,ISO-8859-1 又叫做 Latin-1,所以現在你應該知道,有的地方比如 MySQL 裏的字符集顯示 Latin-1,不要陌生,他只是 ISO-8859-1 的別名。

還是那句話,字符編碼就是一個字典或者對照表,說什麼都不如列個表實在,ISO-8859-1 的對照表(只列出擴展了 ASCII 的部分)詳見附錄 ISO-8859-1

五、字符編碼繼續發展(來中國了)

GB2312

計算機開水普及到了中國,於是一切就不一樣了。原本用一個字節就解決所有的符號編碼,在中國是行不通的。於是 1981 年國家標準化管理委員會定了一套字符集叫 GB2312,每個漢字符號由兩個字節組成,注意!這裏變成了兩個字節。理論上它可以表示 65536 個字符,不過它只收錄了 7445 個字符,6763 個漢字和 682 個其他字符,同時它能夠兼容 ASCII。

GBK

GB2312 所收錄的漢字已經覆蓋中國大陸 99.75% 的使用頻率,但是對一些罕見的字和繁體字還有很多少數民族使用的字符都沒法處理,於是後來就在 GB2312 的基礎上創建了一種叫 GBK 的字符編碼,GBK 不僅收錄了 27484 個漢字,同時還收錄了藏文、蒙文、維吾爾文等主要的少數民族文字。GBK 是利用了 GB2312 中未被使用的編碼空間上進行擴充,所以它能完全兼容 GB2312 和 ASCII。

BIG5

臺灣地區繁體中文標準字符集,採用雙字節編碼,共收錄 13053 箇中文字,1984 年實施。

GB18030 編碼

2000 年 3 月 17 日發佈的漢字編碼國家標準,是對 GBK 編碼的擴充,覆蓋中文、日文、朝鮮語和中國少數民族文字,其中收錄 27484 個漢字。GB18030 字符集採用單字節、雙字節和四字節三種方式對字符編碼。兼容 GBK 和 GB2312 字符集。

中文字符集總結

簡單總結下上面的就是,ASCII < GB2312 < GBK < GB18030,後者是前者的擴充,也即兼容了前者。然後 BIG5 是臺灣字符集,單獨的一套。

中文字符集圖示

這裏拿最常用的 GBK 編碼舉例,GBK 的中文編碼是雙字節來表示的,英文編碼是用 ASCII 碼錶示的,既用單字節表示。但 GBK 編碼表中也有英文字符的雙字節表示形式,所以英文字母可以有 2 種 GBK 表示方式。爲區分中文,將其最高位都定成 1。英文單字節最高位都爲 0。當用 GBK 解碼時,若高字節最高位爲 0,則用 ASCII 碼錶解碼;若高字節最高位爲 1,則用 GBK 編碼表解碼。你可以看到上圖中第一個字節在 00~7F(二進制 00000000~01111111,所以第一位是 0) 之間的都是 ASCII。

理論上說,中文字符編碼也應該列一個對照表,無奈它實在是太多了,不但漢字數量多,而且編碼方式也多。所以這裏只列一下數量最少的 GB2312 ,而且用鏈接的形式給你。

GB2312 簡體中文編碼表

六、字符編碼終極發展(遍佈全球)

Unicode

跟 ISO-8859 的出現原因一樣,只不過這次範圍擴大到了全世界。當然世界各國都有自己國家的字符編碼發展歷史,這裏就沒必要一一展開了。1991 年,國際標準化組織和統一碼聯盟組織退出了 Unicode 項目,目的就是同一全世界的所有字符。

你可能知道 Unicode 分 UTF-8、UTF-16、UCS-2 等,而 ISO-8859 也分 ISO-8859-1、ISO-8859-2……你會不會覺得它們是一樣的道理呢?錯!

  • ISO-8859 是一個字符集的系列,分成 ISO-8859-1、ISO-8859-2 等好多字符集,而每個字符集對應的編碼方式就是 ISO-8859-1 編碼、ISO-8859-2 編碼,是一對一的關係。
  • Unicode 本身就是一個字符集,是全世界所有字符的合集,它並不是字符集系列。而 Unicode 這個字符集特殊的地方在於,他的編碼方式不叫 Unicode 編碼,它的編碼方式有很多種,分別是 UTF-8 編碼、UTF-16 編碼等。

所以字符集系列和字符集的區別,最好的例子就是 ISO-8859;而字符集和字符編碼的區別,最好的例子就是 Unicode。

捋清了這個關係,下面我們就可以詳細說說大家心心念唸的 Unicode 了。Unicode 本身並沒有規定一個字符究竟是怎麼編碼,甚至都沒有規定用幾個字節表示,所以也叫可變長度字符編碼。Unicode 只規定了每個字符對應到唯一的代碼值(code point),代碼值從 0000~10FFFF 共 1114112 個值,你曾經看到的很討人厭的 \u0300 這種,就是 Unicode 的代碼值,這種代碼值要想變成真正存儲在機器裏的字符串,一定要進行某種編碼,如下。

ustr = \u0030;
str = ustr.encode("utf-8")

真正存儲的時候需要多少個字節是由具體的編碼格式決定的。比如:字符 「A」用 UTF-8 的格式編碼來存儲就只佔用 1 個字節,用 UTF-16 就佔用 2 個字節,而用 UTF-32 存儲就佔用 4 個字節。而 UTF-8 本身,又不是固定長度的,也是可變長度的。

Unicode UTF-8 byte 數 備註
0000~007F 0XXX XXXX 1
0080~07FF 110X XXXX 10XX XXXX 2
0800~FFFF 1110 XXXX 10XX XXXX 10XX XXXX 3 基本定義範圍:0~FFFF
1 0000~1F FFFF 1111 0XXX 10XX XXXX 10XX XXXX 10XX XXXX 4 Unicode6.1 定義範圍:0~10 FFFF

所以從這裏你可以看出,一般一種編碼方式是如何兼容其他編碼的,又是如何可變長度的。UTF-8 編碼的第一位如果是 0,則只有一個字節,跟 ASCII 編碼完全一樣,所以兼容了。如果是 110 開頭,則是兩個字節,以此類推如上表所示。所以開頭幾位的值,是編碼本身,同時又是判斷是幾個字節數的推碼,可謂是一箭雙鵰。這種設計頗有點像 CPU 中的相聯存儲器的概念。

所以如果再有人問你這個問題:UTF-8 佔幾個字節漢字到底佔幾個字節?你就可以這樣專業而又不裝逼的回答:

首先漢字佔幾個字節這個問題本身就不明確,應該問 Unicode 字符集中的漢字用 UTF-8 編碼方式編碼,佔幾個字節?

那這個問題就演化成了 UTF-8 佔幾個字節。UTF-8 是可變長度字符編碼,所以只能說佔 1~4 個字節。

  • 單字節可編碼的 Unicode 範圍:\u0000~\u007F(0~127)
  • 雙字節可編碼的 Unicode 範圍:\u0080~\u07FF(128~2047)
  • 三字節可編碼的 Unicode 範圍:\u0800~\uFFFF(2048~65535)
  • 四字節可編碼的 Unicode 範圍:\u10000~\u1FFFFF(65536~2097151)

那基於各種歷史的或者是合理性原因,人們把佔用 1 個字節的給了 ASCII;佔 2 個字節的給了拉丁文、希臘文、西裏爾字母、亞美尼亞語、希伯來文等;佔 3 個字節的給了大部分漢字,基本等同於 GBK,含 21000 多個漢字;佔 4 個字節的中日韓超大字符集裏面的漢字,有 5 萬多個。

所以,漢字佔三個字節這句話,應該說成

Unicode 字符集中的大部分漢字,如果用 UTF-8 編碼的話,是佔 3 個字節的。而 UTF-8 編碼本身,是 1~4 個字節的可變長度字符編碼。

七、字符編碼的總結

按時間線

  • 美國線:ASCII --> EASCII --> ISO-8859 --> Unicode
  • 中國線:GB2312 --> GBK --> GB18030 --> Unicode
  • 他國線:... ... --> Unicode

按含義

  • 字符集系列(對應 n 多個字符集):ISO-8859 系列
  • 字符集(對應 n 多個字符編碼):ASCII、ISO-8859-1、GBK、Unicode
  • 字符編碼:ASCII、ISO-8859-1、GBK、UTF-8、UTF-16

按字節數

  • 單字節:ASCII、ISO-8859 系列
  • 雙字節:GB2312、GBK
  • 可變字節:UTF-8、UTF-16

八、爲什麼會產生亂碼

前面說過,編碼和解碼,就是一個查表的過程,正着查是二進制的值到字符,反着查是字符到二進制的數值。所謂亂碼,就是編碼和解碼查的不是一張表嘛。就好比你叫你丈夫的爹爲“公公”,你是查現代漢語詞典編碼出的“公公”兩個字,人家爸爸卻拿着古代漢語詞典來解碼你這個“公公”的含義,這不亂纔怪嘛。

自己構造一個亂碼很簡單,我們用 UTF-8 來編碼一個“你好”這兩個字,再用 GBK 解碼來閱讀,看看會怎麼樣。

  1. 首先新建一個 txt 文件,就叫【亂碼.txt】吧,然後用二進制方式打開它(我用的是 Notepad++,下載了 Hex-Editor 插件)。

  2. 我們查 UTF-8 編碼字典,發現你好兩個字的編碼是“E4BDA0”、“E5A5BD”,我們將編碼輸入。

  3. 好吧你說這哪是 2 進制啊,這不是 16 進制麼。那我們就直接一點,用純 2 進制的方式輸入,“111001001011110110100000”,“111001011010010110111101”。

存在計算機裏都一樣

  1. 返回正常的文本狀態,選擇用 UTF-8 編碼方式查看,發現是正常的“你好”兩個字。但如果切換成 GBK(這裏我選擇了 GB2312,一樣的),就變成了奇怪的文字。

  1. 這很好理解,UTF-8 編碼漢字是 3 個字節,剛剛我們編碼了“你好”,對應的字節序列是 “E4BDA0”、“E5A5BD”,一共 6 個字節。GBK 編碼漢字是 2 個字節,於是解讀成了 “E4BD“、”A0E5“、”A5BD”,三個漢字。那我們查 GBK 碼錶:

你有沒有發現,居然跟我們看到的是一樣的!這還是比較有好的亂碼,起碼還能對應上真正碼錶中存在的漢字。有的亂碼字節數都不對,或者乾脆碼錶中查不到,就難看極了。這就要看各個不同的文本查看軟件怎麼處理了,比如我 GBK 本來是雙字節的,我硬生生把一個字的後一個字節刪了,這種情況 Notepad++ 還算友好,可以讓你看到是因爲少了一個字節出的問題,如果用記事本打開,就是一個大寫的 “?”。

編碼我們都理解了,就是最終寫在計算機內存裏的 01010 字節序列。而對於解碼,似乎還是有一點迷惑,解碼解成了什麼呢?要相信自己的判斷,沒錯,解碼就是解成了我們眼睛看到的這些東西,他們的本質就是屏幕上顯示的光點。比如說漢字,其實解碼我們所查的表,最終對應的就是一個 n*n 的矩陣,最終再經過一些列的轉換,由串口輸出到顯示屏上,矩陣中的 1 就代表有,0 就代表無,經過放大縮小等線性變換,最終達到屏幕上的一個個小光點上,就變成了我們看到的字。老一輩的計算機從業者,有很多人力需要去造這張表,就是把每個編碼對應的這個矩陣畫出來,最終存成字庫。如果你聽老一輩的計算機從業者講述,將聽到很多關於這裏的故事,像“區位碼”,這裏我就不展開說了,其實也是因爲沒經歷過,不太瞭解。

九、如何解決亂碼

上一環節我給你展示了一個文本文件如何產生了亂碼,那如何解決文本文件的編碼呢,很簡單,保存的時候用什麼格式編碼保存的,讀取的時候就用什麼時候讀。比如 Notepad++ 就很清晰,保存和讀取都在【編碼】這個菜單欄裏。

對於記事本,我們似乎沒看到編碼這一項,其實如果你選擇另存爲,一般會有四個編碼選項讓你選擇,分別是 ANSI、Unicode、Unicode big endian、UTF-8。如果你不選擇的話,默認保存是用 ANSI,那 windows 平臺一般是指的 GBK

這裏你可能會困惑,剛剛不是說了 Unicode 不是字符集編碼,而只是字符集麼,這裏怎麼又出現在編碼了。沒錯,這就是字符編碼比較亂的地方之一,命名不規範,有很多潛規則。比如這個記事本的 Unicode:Windows 平臺下默認的 Unicode 編碼爲 Little Endian 的 UTF-16,實際上它還是指的是一個具體的編碼格式,只不過被潛規則在 Windows 平臺下了,讓很多人誤以爲 Unicode 就是特指某種具體的編碼方式。

瀏覽器

剛剛解釋了下記事本的亂碼解決,其實所有工具都是一樣的,只要有文本閱讀的地方,一般都會有設置編碼的地方。那麼我們來看一下最常見也最容易出錯的瀏覽器。我們打開一個網頁發現是亂碼,這尤其經常發生在我們開發測試階段,那麼我們先拋離服務端,單純創建一個亂碼的頁面。

用 Notepad++ 寫一個以 UTF-8 編碼的文件 test.html:

<!DOCTYPE HTML>
<html>
    <head></head>
    <body>
        你好
    </body>
</html>

用 IE 瀏覽器打開,直接亂碼:

而如果我們重新用 GBK 編碼寫一個一模一樣的文件,再用 IE 打開,正常。這是爲什麼呢?原因很簡單,IE 瀏覽器默認用 GBK 去解碼一個 HTML。這又是一個潛規則。

而我們怎麼才能讓它顯示正確呢?你可以強行改瀏覽器的編碼方式,但你搞一個服務,總不能讓用戶去做這個事情吧?一個個試哪個編碼方式正確?即使瀏覽器功能強大到可以智能分析編碼,也最好有一個標識來告訴瀏覽器這個 HTML 是如何編碼的,這個標識就是:

<meta charset = "utf-8"/>

把它加載 header 中:

<!DOCTYPE HTML>
<html>
    <head>
        <meta charset = "utf-8"/>
    </head>
    <body>
        你好
    </body>
</html>

再用 IE 瀏覽器打開,正常!

那麼我們就知道了,頁面產生亂碼,不是我們的問題,要麼是服務端沒有設置這個 meta charset,要麼就是服務端設置了,但實際上編碼響應流的時候卻用了其他編碼方式。當然我們也能自己強行解決,那就是設置瀏覽器的編碼方式,不同瀏覽器設置編碼方式的位置不一樣,而且我個人感覺也很難找,不同瀏覽器的默認編碼方式也不同,而且還有可能有 Unicode 指的是 UTF-8 這樣的潛規則。所以爲了徹底杜絕這個問題,還是在 HTML 文件裏面告知爲好。

服務器

既然瀏覽的頁面亂碼怪服務端,那我就不得不說說服務端這邊的事。

我們寫一個 Spring Boot 程序:

@SpringBootApplication
@Controller
public class JavamateSpringbootApplication {

    public static void main(String[] args) {
        SpringApplication.run(JavamateSpringbootApplication.class, args);
    }

    @RequestMapping("hello")
    @ResponseBody
    public String hello() {
        return "你好";
    }
}

瀏覽器訪問 /hello,完美顯示“你好”,並沒有亂碼。

正因爲 Spring Boot 爲我們做了太多事,才這麼容易發生不亂碼的情況。其實與其說爲什麼會亂碼,不如解釋解釋爲什麼這段代碼沒有亂碼。

首先沒有亂碼,一定是編解碼用的是同一套。那編碼是什麼呢,這裏就又涉及到潛規則了,Spring Boot 默認情況下,@ResponseBody 會用 UTF-8 對字符串進行編碼,而且會爲響應體設置一個相應頭:

Content-Type: text/javascript; charset=UTF-8

解碼方面,IE 瀏覽器默認是 GBK,但你響應體裏有這個頭了,那 IE 會改成用 UTF-8 解碼。

不知道你有沒有經歷過 Tomcat 時代的 ISO-8859-1 亂碼的時代,那時候沒有這些強大的開發框架,好多地方可能要 response 直接 write 數據出去,而 Tomcat 此時的默認編碼是 ISO-8859-1。所以那時候好多地方都需要手動改成 UTF-8。由於 UTF-8 漸漸變成了國際標準,Spring Boot 框架也將內嵌的 Tomcat 默認編碼格式改成了 UTF-8。

那我們怎麼搞出一個亂碼呢?很簡單,我們用默認編碼格式爲 ISO-8859-1 的 Response 直接 write 出去,而不依賴於框架。

@RequestMapping("hello2")
public void hello2(HttpServletResponse response) throws IOException {
    PrintWriter writer = response.getWriter();
    writer.println("你好");
    writer.flush();
}

瀏覽器打開,直接亂碼。

其實更直觀的寫法應該是這樣,拋開所有默認的外套:

@RequestMapping("hello2")
public void hello2(HttpServletResponse response) throws IOException {
    response.setCharacterEncoding("gbk");
    response.addHeader("Content-Type", "text/html");
    ServletOutputStream out = response.getOutputStream();
    out.write("你好".getBytes("utf-8"));
    out.flush();
}

瀏覽器打開,看到了我們熟悉的亂碼。

浣犲ソ

我們看到代碼中,直接表達了:將“你好”用 UTF-8 格式編碼,並通過響應頭告訴瀏覽器,用 GBK 的方式解碼。這自然就亂碼了。

現在的服務端框架,已經達成了用 UTF-8 作爲編解碼標準的共識,而且 String 的 getBytes 方法默認的也是 UTF-8,也可以通過 file.encoding 參數配置。所以現在基本不用擔心亂碼問題了。在 Tomcat 亂碼滿天飛的時代,解決亂碼問題也無非是:

  • 看字符串本身的編碼
  • 看設置迴響應頭的編碼
  • 看 HTML 文件的 meta 屬性的編碼

附錄後文末有驚喜

十、附錄

ASCII 和 ISO-8859-1 的編碼表

ASCII

Bin Oct Dec Hex 縮寫/字符 解釋
(二進制) (八進制) (十進制) (十六進制)
0000 0000 0 0 0x00 NUL(null) 空字符
0000 0001 1 1 0x01 SOH(start of headline) 標題開始
0000 0010 2 2 0x02 STX (start of text) 正文開始
0000 0011 3 3 0x03 ETX (end of text) 正文結束
0000 0100 4 4 0x04 EOT (end of transmission) 傳輸結束
0000 0101 5 5 0x05 ENQ (enquiry) 請求
0000 0110 6 6 0x06 ACK (acknowledge) 收到通知
0000 0111 7 7 0x07 BEL (bell) 響鈴
0000 1000 10 8 0x08 BS (backspace) 退格
0000 1001 11 9 0x09 HT (horizontal tab) 水平製表符
0000 1010 12 10 0x0A LF (NL line feed, new line) 換行鍵
0000 1011 13 11 0x0B VT (vertical tab) 垂直製表符
0000 1100 14 12 0x0C FF (NP form feed, new page) 換頁鍵
0000 1101 15 13 0x0D CR (carriage return) 回車鍵
0000 1110 16 14 0x0E SO (shift out) 不用切換
0000 1111 17 15 0x0F SI (shift in) 啓用切換
0001 0000 20 16 0x10 DLE (data link escape) 數據鏈路轉義
0001 0001 21 17 0x11 DC1 (device control 1) 設備控制 1
0001 0010 22 18 0x12 DC2 (device control 2) 設備控制 2
0001 0011 23 19 0x13 DC3 (device control 3) 設備控制 3
0001 0100 24 20 0x14 DC4 (device control 4) 設備控制 4
0001 0101 25 21 0x15 NAK (negative acknowledge) 拒絕接收
0001 0110 26 22 0x16 SYN (synchronous idle) 同步空閒
0001 0111 27 23 0x17 ETB (end of trans. block) 結束傳輸塊
0001 1000 30 24 0x18 CAN (cancel) 取消
0001 1001 31 25 0x19 EM (end of medium) 媒介結束
0001 1010 32 26 0x1A SUB (substitute) 代替
0001 1011 33 27 0x1B ESC (escape) 換碼(溢出)
0001 1100 34 28 0x1C FS (file separator) 文件分隔符
0001 1101 35 29 0x1D GS (group separator) 分組符
0001 1110 36 30 0x1E RS (record separator) 記錄分隔符
0001 1111 37 31 0x1F US (unit separator) 單元分隔符
0010 0000 40 32 0x20 (space) 空格
0010 0001 41 33 0x21 ! 歎號
0010 0010 42 34 0x22 " 雙引號
0010 0011 43 35 0x23 # 井號
0010 0100 44 36 0x24 $ 美元符
0010 0101 45 37 0x25 % 百分號
0010 0110 46 38 0x26 & 和號
0010 0111 47 39 0x27 ' 閉單引號
0010 1000 50 40 0x28 ( 開括號
0010 1001 51 41 0x29 ) 閉括號
0010 1010 52 42 0x2A * 星號
0010 1011 53 43 0x2B + 加號
0010 1100 54 44 0x2C , 逗號
0010 1101 55 45 0x2D - 減號/破折號
0010 1110 56 46 0x2E . 句號
0010 1111 57 47 0x2F / 斜槓
0011 0000 60 48 0x30 0 字符 0
0011 0001 61 49 0x31 1 字符 1
0011 0010 62 50 0x32 2 字符 2
0011 0011 63 51 0x33 3 字符 3
0011 0100 64 52 0x34 4 字符 4
0011 0101 65 53 0x35 5 字符 5
0011 0110 66 54 0x36 6 字符 6
0011 0111 67 55 0x37 7 字符 7
0011 1000 70 56 0x38 8 字符 8
0011 1001 71 57 0x39 9 字符 9
0011 1010 72 58 0x3A : 冒號
0011 1011 73 59 0x3B ; 分號
0011 1100 74 60 0x3C < 小於
0011 1101 75 61 0x3D = 等號
0011 1110 76 62 0x3E > 大於
0011 1111 77 63 0x3F ? 問號
0100 0000 100 64 0x40 @ 電子郵件符號
0100 0001 101 65 0x41 A 大寫字母 A
0100 0010 102 66 0x42 B 大寫字母 B
0100 0011 103 67 0x43 C 大寫字母 C
0100 0100 104 68 0x44 D 大寫字母 D
0100 0101 105 69 0x45 E 大寫字母 E
0100 0110 106 70 0x46 F 大寫字母 F
0100 0111 107 71 0x47 G 大寫字母 G
0100 1000 110 72 0x48 H 大寫字母 H
0100 1001 111 73 0x49 I 大寫字母 I
1001010 112 74 0x4A J 大寫字母 J
0100 1011 113 75 0x4B K 大寫字母 K
0100 1100 114 76 0x4C L 大寫字母 L
0100 1101 115 77 0x4D M 大寫字母 M
0100 1110 116 78 0x4E N 大寫字母 N
0100 1111 117 79 0x4F O 大寫字母 O
0101 0000 120 80 0x50 P 大寫字母 P
0101 0001 121 81 0x51 Q 大寫字母 Q
0101 0010 122 82 0x52 R 大寫字母 R
0101 0011 123 83 0x53 S 大寫字母 S
0101 0100 124 84 0x54 T 大寫字母 T
0101 0101 125 85 0x55 U 大寫字母 U
0101 0110 126 86 0x56 V 大寫字母 V
0101 0111 127 87 0x57 W 大寫字母 W
0101 1000 130 88 0x58 X 大寫字母 X
0101 1001 131 89 0x59 Y 大寫字母 Y
0101 1010 132 90 0x5A Z 大寫字母 Z
0101 1011 133 91 0x5B [ 開方括號
0101 1100 134 92 0x5C \ 反斜槓
0101 1101 135 93 0x5D ] 閉方括號
0101 1110 136 94 0x5E ^ 脫字符
0101 1111 137 95 0x5F _ 下劃線
0110 0000 140 96 0x60 ` 開單引號
0110 0001 141 97 0x61 a 小寫字母 a
0110 0010 142 98 0x62 b 小寫字母 b
0110 0011 143 99 0x63 c 小寫字母 c
0110 0100 144 100 0x64 d 小寫字母 d
0110 0101 145 101 0x65 e 小寫字母 e
0110 0110 146 102 0x66 f 小寫字母 f
0110 0111 147 103 0x67 g 小寫字母 g
0110 1000 150 104 0x68 h 小寫字母 h
0110 1001 151 105 0x69 i 小寫字母 i
0110 1010 152 106 0x6A j 小寫字母 j
0110 1011 153 107 0x6B k 小寫字母 k
0110 1100 154 108 0x6C l 小寫字母 l
0110 1101 155 109 0x6D m 小寫字母 m
0110 1110 156 110 0x6E n 小寫字母 n
0110 1111 157 111 0x6F o 小寫字母 o
0111 0000 160 112 0x70 p 小寫字母 p
0111 0001 161 113 0x71 q 小寫字母 q
0111 0010 162 114 0x72 r 小寫字母 r
0111 0011 163 115 0x73 s 小寫字母 s
0111 0100 164 116 0x74 t 小寫字母 t
0111 0101 165 117 0x75 u 小寫字母 u
0111 0110 166 118 0x76 v 小寫字母 v
0111 0111 167 119 0x77 w 小寫字母 w
0111 1000 170 120 0x78 x 小寫字母 x
0111 1001 171 121 0x79 y 小寫字母 y
0111 1010 172 122 0x7A z 小寫字母 z
0111 1011 173 123 0x7B { 開花括號
0111 1100 174 124 0x7C \
0111 1101 175 125 0x7D } 閉花括號
0111 1110 176 126 0x7E ~ 波浪號
0111 1111 177 127 0x7F DEL (delete) 刪除

ISO-8859-1

DEC OCT HEX BIN Symbol Description
128 200 80 10000000 Euro sign
129 201 81 10000001
130 202 82 10000010 Single low-9 quotation mark
131 203 83 10000011 ƒ Latin small letter f with hook
132 204 84 10000100 Double low-9 quotation mark
133 205 85 10000101 Horizontal ellipsis
134 206 86 10000110 Dagger
135 207 87 10000111 Double dagger
136 210 88 10001000 ˆ Modifier letter circumflex accent
137 211 89 10001001 Per mille sign
138 212 8A 10001010 Š Latin capital letter S with caron
139 213 8B 10001011 Single left-pointing angle quotation
140 214 8C 10001100 ΠLatin capital ligature OE
141 215 8D 10001101
142 216 8E 10001110 Ž Latin captial letter Z with caron
143 217 8F 10001111
144 220 90 10010000
145 221 91 10010001 Left single quotation mark
146 222 92 10010010 Right single quotation mark
147 223 93 10010011 Left double quotation mark
148 224 94 10010100 Right double quotation mark
149 225 95 10010101 Bullet
150 226 96 10010110 En dash
151 227 97 10010111 Em dash
152 230 98 10011000 ˜ Small tilde
153 231 99 10011001 Trade mark sign
154 232 9A 10011010 š Latin small letter S with caron
155 233 9B 10011011 Single right-pointing angle quotation mark
156 234 9C 10011100 œ Latin small ligature oe
157 235 9D 10011101
158 236 9E 10011110 ž Latin small letter z with caron
159 237 9F 10011111 Ÿ Latin capital letter Y with diaeresis
160 240 A0 10100000 Non-breaking space
161 241 A1 10100001 ¡ Inverted exclamation mark
162 242 A2 10100010 ¢ Cent sign
163 243 A3 10100011 £ Pound sign
164 244 A4 10100100 ¤ Currency sign
165 245 A5 10100101 ¥ Yen sign
166 246 A6 10100110 ¦ Pipe, Broken vertical bar
167 247 A7 10100111 § Section sign
168 250 A8 10101000 ¨ Spacing diaeresis - umlaut
169 251 A9 10101001 © Copyright sign
170 252 AA 10101010 ª Feminine ordinal indicator
171 253 AB 10101011 « Left double angle quotes
172 254 AC 10101100 ¬ Not sign
173 255 AD 10101101 Soft hyphen
174 256 AE 10101110 ® Registered trade mark sign
175 257 AF 10101111 ¯ Spacing macron - overline
176 260 B0 10110000 ° Degree sign
177 261 B1 10110001 ± Plus-or-minus sign
178 262 B2 10110010 ² Superscript two - squared
179 263 B3 10110011 ³ Superscript three - cubed
180 264 B4 10110100 ´ Acute accent - spacing acute
181 265 B5 10110101 µ Micro sign
182 266 B6 10110110 Pilcrow sign - paragraph sign
183 267 B7 10110111 · Middle dot - Georgian comma
184 270 B8 10111000 ¸ Spacing cedilla
185 271 B9 10111001 ¹ Superscript one
186 272 BA 10111010 º Masculine ordinal indicator
187 273 BB 10111011 » Right double angle quotes
188 274 BC 10111100 ¼ Fraction one quarter
189 275 BD 10111101 ½ Fraction one half
190 276 BE 10111110 ¾ Fraction three quarters
191 277 BF 10111111 ¿ Inverted question mark
192 300 C0 11000000 À Latin capital letter A with grave
193 301 C1 11000001 Á Latin capital letter A with acute
194 302 C2 11000010 Â Latin capital letter A with circumflex
195 303 C3 11000011 Ã Latin capital letter A with tilde
196 304 C4 11000100 Ä Latin capital letter A with diaeresis
197 305 C5 11000101 Å Latin capital letter A with ring above
198 306 C6 11000110 Æ Latin capital letter AE
199 307 C7 11000111 Ç Latin capital letter C with cedilla
200 310 C8 11001000 È Latin capital letter E with grave
201 311 C9 11001001 É Latin capital letter E with acute
202 312 CA 11001010 Ê Latin capital letter E with circumflex
203 313 CB 11001011 Ë Latin capital letter E with diaeresis
204 314 CC 11001100 Ì Latin capital letter I with grave
205 315 CD 11001101 Í Latin capital letter I with acute
206 316 CE 11001110 Î Latin capital letter I with circumflex
207 317 CF 11001111 Ï Latin capital letter I with diaeresis
208 320 D0 11010000 Ð Latin capital letter ETH
209 321 D1 11010001 Ñ Latin capital letter N with tilde
210 322 D2 11010010 Ò Latin capital letter O with grave
211 323 D3 11010011 Ó Latin capital letter O with acute
212 324 D4 11010100 Ô Latin capital letter O with circumflex
213 325 D5 11010101 Õ Latin capital letter O with tilde
214 326 D6 11010110 Ö Latin capital letter O with diaeresis
215 327 D7 11010111 × Multiplication sign
216 330 D8 11011000 Ø Latin capital letter O with slash
217 331 D9 11011001 Ù Latin capital letter U with grave
218 332 DA 11011010 Ú Latin capital letter U with acute
219 333 DB 11011011 Û Latin capital letter U with circumflex
220 334 DC 11011100 Ü Latin capital letter U with diaeresis
221 335 DD 11011101 Ý Latin capital letter Y with acute
222 336 DE 11011110 Þ Latin capital letter THORN
223 337 DF 11011111 ß Latin small letter sharp s - ess-zed
224 340 E0 11100000 à Latin small letter a with grave
225 341 E1 11100001 á Latin small letter a with acute
226 342 E2 11100010 â Latin small letter a with circumflex
227 343 E3 11100011 ã Latin small letter a with tilde
228 344 E4 11100100 ä Latin small letter a with diaeresis
229 345 E5 11100101 å Latin small letter a with ring above
230 346 E6 11100110 æ Latin small letter ae
231 347 E7 11100111 ç Latin small letter c with cedilla
232 350 E8 11101000 è Latin small letter e with grave
233 351 E9 11101001 é Latin small letter e with acute
234 352 EA 11101010 ê Latin small letter e with circumflex
235 353 EB 11101011 ë Latin small letter e with diaeresis
236 354 EC 11101100 ì Latin small letter i with grave
237 355 ED 11101101 í Latin small letter i with acute
238 356 EE 11101110 î Latin small letter i with circumflex
239 357 EF 11101111 ï Latin small letter i with diaeresis
240 360 F0 11110000 ð Latin small letter eth
241 361 F1 11110001 ñ Latin small letter n with tilde
242 362 F2 11110010 ò Latin small letter o with grave
243 363 F3 11110011 ó Latin small letter o with acute
244 364 F4 11110100 ô Latin small letter o with circumflex
245 365 F5 11110101 õ Latin small letter o with tilde
246 366 F6 11110110 ö Latin small letter o with diaeresis
247 367 F7 11110111 ÷ Division sign
248 370 F8 11111000 ø Latin small letter o with slash
249 371 F9 11111001 ù Latin small letter u with grave
250 372 FA 11111010 ú Latin small letter u with acute
251 373 FB 11111011 û Latin small letter u with circumflex
252 374 FC 11111100 ü Latin small letter u with diaeresis
253 375 FD 11111101 ý Latin small letter y with acute
254 376 FE 11111110 þ Latin small letter thorn
255 377 FF 11111111 ÿ Latin small letter y with diaeresis

逗你呢,沒什麼驚喜。

但這樣搞大家有點於心不忍

給大家出一個題吧,1 斤 100 元的紙幣和 100 斤 1 元的紙幣,你選拿個?公衆號下期文章揭曉答案

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章