前置閲讀:
- Unicode 與 JavaScript 詳解
- 字符編碼筆記:ASCII,Unicode 和 UTF-8
- 談談Unicode編碼
- How to teach endian
- The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
什麼是字符集
顧名思義,字符集就是字符的集合 。
什麼是 ASCII
ASCII ((American Standard Code for Information Interchange): 美國信息交換標準代碼)是基於拉丁字母的一套電腦編碼系統,主要用於顯示現代英語和其他西歐語言。
在計算機中,所有的數據在存儲和運算時都要使用二進制數表示(因為計算機用高電平和低電平分別表示1和0),例如,像 a、b、c、d 這樣的 52 個字母(包括大寫)以及 0、1 等數字還有一些常用的符號(例如 *、#、@ 等)
既然要使用二進制數來表示字符,那具體用哪些二進制數字表示哪個符號,當然每個人都可以約定自己的一套(這就叫編碼),而大家如果要想互相通信而不造成混亂,那麼大家就必須使用相同的編碼規則,於是美國有關的標準化組織就出台了 ASCII 編碼,統一規定了上述常用符號用哪些二進制數來表示。
美國信息交換標準代碼是由美國國家標準學會(American National Standard Institute , ANSI ) 制定的,是一種標準的單字節字符編碼方案,用於基於文本的數據。
它最初是美國國家標準,供不同計算機在相互通信時用作共同遵守的西文字符編碼標準,後來它被國際標準化組織(International Organization for Standardization, ISO)定為國際標準,稱為 ISO 646 標準。
簡單的説 ASCII 碼錶就是一套最基礎的編碼庫或字符集,裏面包括了字母、數字、符號以及一些控制字符。
什麼是 Unicode
Unicode 是國際組織制定的可以容納世界上所有文字和符號的字符編碼方案,通過 Unicode 編碼規則出來的字符的集合便叫做 Unicode 字符集。
計算機只能處理數字(0、1),如果要處理文本,就必須先把文本轉換為數字才能處理。最早的計算機在設計時採用 8 個比特(bit)作為一個字節(byte)。
一個字節能表示的最大的整數就是 255(28-1=255),而 ASCII 編碼,佔用 0 ~ 127 用來表示大小寫英文字母、數字和一些符號,這個編碼表被稱為 ASCII 編碼,比如大寫字母 A 的編碼是 65,小寫字母 z 的編碼是 122。
如果要表示中文,顯然一個字節是不夠的,至少需要兩個字節,而且還不能和 ASCII 編碼衝突,所以,中國製定了 GB2312 編碼,用來把中文編進去。
類似的,日文和韓文等其他語言也有這個問題。為了統一所有文字的編碼,Unicode 應運而生。Unicode 把所有語言都統一到一套編碼裏,這樣就不會再有亂碼問題了。
Unicode 用若干個字節表示一個字符,原有的英文編碼如果想從單字節變成雙字節,只需要把高字節全部填為 0 就可以。在表示一個 Unicode 的字符時,通常會用 “U+” 然後緊接着一組十六進制的數字來表示這一個字符。
目前的 Unicode 字符分為 17 組編排,0x0000 至 0x10FFFF,每組稱為平面(Plane),而每平面擁有 65536 (即216)個碼位,共 1,114,112 個。然而目前只用了少數平面。
| 平面 | 始末字符值 | 中文名稱 | 英文名稱 |
|---|---|---|---|
| 0號平面 | U+0000 - U+FFFF | 基本多文種平面 | Basic Multilingual Plane,簡稱 BMP |
| 1號平面 | U+10000 - U+1FFFF | 多文種補充平面 | Supplementary Multilingual Plane,簡稱 SMP |
| 2號平面 | U+20000 - U+2FFFF | 表意文字補充平面 | Supplementary Ideographic Plane,簡稱 SIP |
| 3號平面 | U+30000 - U+3FFFF | 表意文字第三平面 | Tertiary Ideographic Plane,簡稱 TIP |
| 4號平面 至 13號平面 | U+40000 - U+DFFFF | (尚未使用) | |
| 14號平面 | U+E0000 - U+EFFFF | 特別用途補充平面 | Supplementary Special-purpose Plane,簡稱 SSP |
| 15號平面 | U+F0000 - U+FFFFF | 保留作為私人使用區(A區) | Private Use Area-A,簡稱 PUA-A |
| 16號平面 | U+100000 - U+10FFFF | 保留作為私人使用區(B區) | Private Use Area-B,簡稱 PUA-B |
其中平面 15 和平面 16 上只是定義了兩個各佔 65534 個碼位的專用區(Private Use Area),分別是0xF0000 - 0xFFFFD 和 0x100000 -0x10FFFD。所謂專用區,就是保留給大家放自定義字符的區域,可以簡寫為PUA。
平面 0 也有專用區:
0xD800-0xDFFF,共 2048 個碼位,是一個被稱作代理區(Surrogate)的特殊區域。代理區的目的是用兩個 UTF-16 字符表示 BMP 以外的字符。
Unicode 只規定了每個字符的碼點,到底用什麼樣的字節序表示這個碼點,就涉及到編碼方法。
Unicode 字符集有多種編碼方式,分別是 UTF-8、UTF-16 和 UTF-32 /...
什麼是 UTF-32
由於 Unicode 碼點最大佔用 4 個字節,如果每個碼點固定使用四個字節表示,字節內容一一對應碼點。這種編碼方法就叫做UTF-32。比如,碼點 0 就用四個字節的 0 表示,碼點 59 7D 就在前面加兩個字節的 0 。
UTF-32的優點在於,轉換規則簡單直觀,查找效率高。缺點在於浪費空間,同樣內容的英語文本,它會比ASCII編碼大四倍。這個缺點很致命,導致實際上沒有人使用這種編碼方法,HTML 5標準就明文規定,網頁不得編碼成UTF-32。
人們真正需要的是一種節省空間的編碼方法,這導致了UTF-8的誕生。
什麼是 UTF-8
UTF-8是一種變長的編碼方法,字符長度從1個字節到4個字節不等。
越是常用的字符,字節越短,最前面的128個字符,只使用1個字節表示,與ASCII碼完全相同。
UTF-8 以字節為單位對 Unicode 進行編碼。 UTF-8 的編碼方式如下:
- 對於單字節的符號,字節的第一位設為
0,後面7位為這個符號的 Unicode 碼。因此對於英語字母,UTF-8 編碼和 ASCII 碼是相同的。 - 對於
n字節的符號(n > 1),第一個字節的前n位都設為1,第n + 1位設為0,後面字節的前兩位一律設為10。剩下的沒有提及的二進制位,全部為這個符號的 Unicode 碼。
| Unicode 編碼(十六進制) | UTF-8 字節流(二進制) | x 數量 |
|---|---|---|
| 0000 0000 - 0000 007F | 0xxxxxxx | 7 |
| 0000 0080 - 0000 07FF | 110xxxxx 10xxxxxx | 11 |
| 0000 0800 - 0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx | 16 |
| 0001 0000 - 0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx | 21 |
通過規則可以看出並不是直接把十六進制的 Unicode 碼直接轉成二進制就是 UTF-8 碼,而是通過編碼方式進行轉換,原先 Unicode 編碼下最大碼點是 10FFFF 大小不超過 3 個字節,但是轉換成 UTF-8 後最大需要用 4 個字節去表示。
這個規則的好處在於能夠使解析的時候快速確認當前字符需要多少個字節。<u>UTF-8 編碼的最大長度是 4 個字節</u>。
UTF-8 的特點是對不同範圍的字符使用不同長度的編碼。對於 0x00 - 0x7F 之間的字符,UTF-8 編碼與 ASCII 編碼完全相同。
從上表可以看出,4 字節模板有 21個 x,即可以容納 21 位二進制數字。Unicode 的最大碼位 0x10FFFF 也只有21位。編碼舉例如下:
- “漢” 字的 Unicode 編碼是
0x6C49。0x6C49在0x0800-0xFFFF之間,需要使用 3 字節模板:1110xxxx 10xxxxxx 10xxxxxx。將0x6C49寫成二進制是:0110 1100 0100 1001, 用這個比特流依次代替模板中的 x,得到:11100110 10110001 10001001,即E6 B1 89。這裏的E6 B1 89便是“漢” 字的 UTF-8 編碼。當然原先佔兩個字節的 Unicode 碼點的進行 UTF-8 編碼後的碼點佔 3 個字節; - Unicode 編碼
0x20C30在0x010000-0x10FFFF之間,使用 4 字節模板:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx。將0x20C30寫成 21位二進制數字(不足21位就在前面補0):0 0010 0000 1100 0011 0000,用這個比特流依次代替模板中的x,得到:11110000 10100000 10110000 10110000,即`F0 A0 B0 B0;
什麼是 UTF-16
UTF-16編碼介於UTF-32與UTF-8之間,同時結合了定長和變長兩種編碼方法的特點。
它的編碼規則很簡單:基本平面的字符佔用2個字節,輔助平面的字符佔用4個字節。也就是説,UTF-16的編碼長度要麼是2個字節(U+0000到U+FFFF),要麼是4個字節(U+010000到U+10FFFF)。
於是就有一個問題,當我們遇到兩個字節,怎麼看出它本身是一個字符,還是需要跟其他兩個字節放在一起解讀?
前面在 Unicode 部分説到,在基本平面內,從 U+D800 到 U+DFFF 是一個空段,即這些碼點不對應任何字符。因此,這個空段可以用來映射輔助平面的字符。
具體來説,輔助平面的字符位共有220個,也就是説,對應這些字符至少需要 20 個二進制位。UTF-16 將這 20 位拆成兩半,前 10 位映射在 U+D800 到 U+DBFF(空間大小210),稱為高位(H),後 10 位映射在 U+DC00 到 U+DFFF(空間大小210),稱為低位(L)。這意味着,一個輔助平面的字符,被拆成兩個基本平面的字符表示。
所以,在UTF-16 編碼下,當我們遇到兩個字節,發現它的碼點在 U+D800 到 U+DBFF 之間,就可以斷定,緊跟在後面的兩個字節的碼點,應該在 U+DC00 到 U+DFFF 之間,這四個字節必須放在一起解讀。
什麼是字節序
先看字節序的定義,援引維基百科
Endianness is the sequential order in which bytes are arranged into larger numerical values when stored in memory or when transmitted over digital links.
簡單來説,字節序就是字節之間的順序,當傳輸或者存儲時,如果數字超過1個字節,需要指定字節間的順序。字節序用英語説就是 byte order mark,簡稱BOM。
字節序問題僅存在於某種編碼下計算機一次讀取字符大小大於一個字節的時候。
字節序一般分為大端字節序或小端字節序,兩種字節序的共同存在完全是歷史原因。採用什麼順序更多的是出於數值處理上的考量。對於數值的不同操作不同的字節序性能也不同,當然如果數值大小不超過一個字節也就不需要擔心什麼順序了。
大端順序是網絡協議中的主要順序,例如在 Internet協議套件中,它被稱為網絡順序,先傳輸最高有效字節。相反,小字節序是處理器體系結構(x86,大多數 ARM 實現,基本 RISC-V 實現)及其關聯內存的主要排序方式。
文件格式則可以使用任何一種順序:有些格式將兩者混合使用。那對文件系統而言計算機怎麼知道某一個文件到底採用哪一種方式編碼?
Unicode 規範定義,每一個文件的最前面分別加入一個表示編碼順序的字符,這個字符的名字叫做"零寬度非換行空格"(zero width no-break space)。
如果一個文本文件的頭兩個字節是FE FF,就表示該文件採用大端方式;如果頭兩個字節是FF FE,就表示該文件採用小端方式。
UTF 的字節序和 BOM
引用至 How to teach endian 的一段話:
One of the major disciplines in computer science is parsing/formatting. This is the process of converting the external format of data (file formats, network protocols, hardware registers) into the internal format (the data structures that software operates on).An external format must be well-defined. What the first byte means must be written down somewhere, then what the second byte means, and so on. For Internet protocols, these formats are written in RFCs, such as RFC 791 for the "Internet Protocol". For file formats, these are written in documents, such as those describing GIF files, JPEG files, MPEG files, and so forth.
翻譯過來就是:
解析/格式化是計算機科學的主要學科之一。這是將數據的外部格式(文件格式,網絡協議,硬件寄存器)轉換為內部格式(軟件所操作的數據結構)的過程。外部格式必須定義明確。必須將第一個字節的含義寫在某個地方,然後將第二個字節的含義寫下,依此類推。對於Internet協議,這些格式以 RFC 編寫,例如“ Internet協議”的 RFC 791。對於文件格式,這些格式寫在文檔中,例如描述 GIF 文件,JPEG 文件,MPEG 文件等的文檔。
Unicode 規範中推薦的標記字節順序的方法是 BOM。BOM 不是 “Bill Of Material” 的 BOM 表,而是 Byte Order Mark。
在 UCS 編碼中有一個叫做 "ZERO WIDTH NO-BREAK SPACE” 的字符,它的編碼是 FEFF。而 FFFE 在 UCS 中是不存在的字符,所以不應該出現在實際傳輸中。
UCS 規範建議我們在傳輸字節流前,先傳輸字符 "ZERO WIDTH NO-BREAK SPACE"。
這樣如果接收者收到 FEFF,就表明這個字節流是 Big-Endian 的;如果收到 FFFE ,就表明這個字節流是 Little-Endian 的。因此字符 "ZERO WIDTH NO-BREAK SPACE” 又被稱作 BOM。
UTF-8 不需要 BOM 來表明字節順序,但可以用 BOM 來表明編碼方式。字符 "ZERO WIDTH NO-BREAK SPACE” 的 UTF-8 編碼是 EF BB BF 所以如果接收者收到以 EF BB BF 開頭的字節流,就知道這是 UTF-8 編碼了。
舉例如下(這裏假設每個內存地址保存一個字節數據):
| 字節格式 | 文本內容 | 16 進制 | 佔用內存大小 | 內存地址 |
|---|---|---|---|---|
| UTF-8 | 1 | 31 | 1 byte | 01 |
| UTF-8 帶 BOM | 1 | EF BB BF 31 | 4 byte | 01~04 |
如上表所示:如果我們單純保存一個內容為 “1”(Unicode 編碼為 0x31)的一個文本數據,選擇帶不帶 BOM 保存的內容是不一致的,針對第一種我們明確的使用了 UTF-8 的編碼進行存儲,如果需要重新加載這個文本數據,將數據從內存(或指定存儲結構)加載出來(這裏只有一個字節,文件大小文件地址等在文件元信息可以獲取),如何展示這個加載數據取決於我們選擇什麼編碼方式,由於我們是使用特定的格式(UTF-8)寫入,所以我們需要指明使用特定的格式( UTF-8) 去讀取才能正確讀取出文本 “1”,否則如果我們選擇直接展示16 進制數據的話得到的內容便是 31。
現在大部分數據加載工具都會設定默認的編碼方式,譬如文本工具等基本默認編碼方式都是 UTF-8。那為了讓某些未設置默認讀取方式的數據加載工具能正確識別數據編碼,便需要我們在寫入數據時優先寫入 BOM,如上表 文本 1 帶上 BOM 後寫入內容將多佔用 3 個字節。有了這 3 個字節的 BOM 數據加載方便清楚接下來使用 UTF-8 去解析內容。
| 字節格式 | 文本內容 | 16 進制 | 佔用內存大小 | 內存地址 |
|---|---|---|---|---|
| UTF-8 | 我 | E6 88 91 | 3 byte | 01~03 |
| UTF-8 帶 BOM | 我 | EF BB BF E6 88 91 | 6 byte | 01~06 |
中文 “我” 的 Unicode 編碼為 0x6211,二進制為 0110 0010 0001 0001 根據前文的 Unicode UTF -8 編碼規則得出 “我” 的 UTF-8
屬於範圍 0000 0800 - 0000 FFFF ,替換模板為 1110xxxx 10xxxxxx 10xxxxxx 帶入模板後得出二進制為: 11100110 10001000 10010001 轉換成 16 進制便是 E6 88 91。
如果是使用 UTF-16 編碼:
UTF-16的編碼長度要麼是2個字節(U+0000 到 U+FFFF),要麼是4個字節(U+010000 到 U+10FFFF)。
| 字節格式 | 文本內容 | 16 進制 | 佔用內存大小 | 內存地址 |
|---|---|---|---|---|
| UTF-16 LE | 我 | 11 62 | 2 byte | 01~02 |
| UTF-16 LE 帶 BOM | 我 | FF FE 11 62 | 4 byte | 01~04 |
| UTF-16 BE | 我 | 62 11 | 2 byte | 01~02 |
| UTF-16 BE 帶 BOM | 我 | FE FF 62 11 | 4 byte | 01~04 |
中文 “我” 的 Unicode 編碼為 6211,UTF-16 沒有特殊的轉換規則,每次讀取或寫入數據必須是 2 個字節,剛剛我字佔用 2 個字節。
如上表所示,如果採用大端字節排序的方式(UTF-16 BE)存儲數據在內存中的表示是與人類閲讀的方式一致的,如果是小端字節序的方式存儲則直觀看起來有點反人類。
主機字節序
網絡字節序與主機字節序是經常導致混淆的兩個概念,網絡字節序是確定的,而主機字節序的多樣性往往是混淆的原因。
基本 x86 系列 CPU 都是 little-endian 的字節序。
舉例説明:
假設每個內存地址單位存一個字節
例子:在內存中雙字 0x01020304(DWORD) 的存儲方式
| 內存地址 | 4000 | 4001 | 4002 | 4003 |
|---|---|---|---|---|
| LE 小端 | 04 | 03 | 02 | 01 |
| BE 大端 | 01 | 02 | 03 | 04 |
或則:
| 內存地址 | LE 小端 | BE 大端 |
|---|---|---|
| 4000 | 04 | 01 |
| 4001 | 03 | 02 |
| 4002 | 02 | 03 |
| 4003 | 01 | 04 |
例子:如果我們將 0x1234abcd 寫入到以 0x0000 開始的內存中,則結果為
| 內存地址 | 0x0000 | 0x0001 | 0x0002 | 0x0003 |
|---|---|---|---|---|
| LE 小端 | 0xcd | 0xab | 0x34 | 0x12 |
| BE 大端 | 0x12 | 0x34 | 0xab | 0xcd |
或則:
| 內存地址 | LE 小端 | BE 大端 |
|---|---|---|
| 0x0000 | 0xcd | 0x12 |
| 0x0001 | 0xab | 0x34 |
| 0x0002 | 0x34 | 0xab |
| 0x0003 | 0x12 | 0xcd |
基本是 :
- 字節角度:字節高位在內存高位代表的是小端字節序,相反字節高位在內存低位便是大端字節序;
- 內存角度:內存低位在字節低位便是小端字節序,相反內存低位放字節高位代表的是大端字節序;
- 總結:字節高位放內存高位或字節低位放內存低位則是小端字節序,否則就是大端字節序。
正常情況下我們都無需去關心主機字節序,因為如何存儲是外部存儲器或則説使驅動需要關心的,我們只需要正常寫入數據和讀取數據即可,其他的字節序的處理無需我們去關心,我們更多需要關心的應該使網絡字節序
網絡字節序
網絡 字節順序 是 TCP/IP 協議中規定好的一種數據表示格式,它與具體的 CPU 類型、操作系統 等無關,從而可以保證數據在不同主機之間傳輸時能夠被正確解釋。網絡字節順序採用 big endian(大端)排序方式。
由於網絡協議中默認使用的是大端字節序,大家都遵守這個規則,自然而然的大家直接用大端字節序去解析網絡數據便可以的到相應的信息,便不需要手動去聲明這個數據包是大端字節序的。當然前提是你發送出去的數據也是大端字節序的(如果你發送出去的數據是小端字節序編碼的自然收取方也得主動用小端的去解析 )。
文件字節序
除了主機字節序以及網絡字節序,還有一種便是我們在保存文件的時候主動聲明使用的字節序。
譬如我們在保存一個文本文件的時候我們可以設置其保存格式為 :UTF-8 / UTF-8 帶 BOM / UTF-16 LE / UTF-16 LE 帶 BOM / UTF-16 BE / UTF-16 BE 帶 BOM / UTF-32 LE / UTF-32 LE 帶 BOM / UTF-32 BE / UTF-32 BE 帶 BOM / UCS….
什麼時候需要關心字節序
使用底層語言譬如 C 語言之類的,我們需要手動將讀取到的內存轉換為指定的數值類型,這個時候就需要知道具體內存的字節序,譬如如果是大端則幾個字節拿出來直接拼在一起可以作為數值使用,否則是小端的話得坐相應的處理才能得到最終的值。高級語言一般不需要我們直接操作內存,運行環境直接幫我們做好處理。
一般開發的時候聲明的變量,如果是數值類型,在運行時,運行環境會自動幫我們處理好數值在內存中的表現,無需過度關心,數值在內存中既有可能大端字節序存儲也有可能是小端字節序存儲,取決於系統的需要。如果是字符類型也同理,運行環境已經會自動幫我們處理好,聲明時是什麼值使用的時候便是什麼值,無需關心在內存中的表現。
跨主機即聯網的時候需要確認發送出去的數據的字節序,接收方需要使用相同的字節序去解析,TCP/IP 協議規定一般使用大端字節序。
Hashbang 註釋
Hashbang 註釋 是一種專門註釋語法
對於 JavaScript 而言,Hashbang 註釋正在 ECMAScript 中標準化(參見 Hashbang 語法建議[https://github.com/tc39/propo...])。
Hashbang 註釋的行為與單行(//)註釋完全相同,但它以 #! 開頭且僅在腳本或模塊的絕對開頭有效。還要注意,在 #! 之前不允許有任何類型的空格。
註釋由 #! 之後的所有字符組成直到第一行的末尾;只允許有一條這樣的註釋。Hashbang 註釋指定特定 JavaScript 解釋器的路徑要用於執行腳本。示例如下:
#!/usr/bin/env node
console.log("Hello world");
注意:JavaScript 中的 Hashbang 註釋模仿 Unix 中的 Shebangs,用於指定適當的解釋器運行文件。
儘管在 Hashbang 註釋之前的 BOM 在瀏覽器中能工作,但不建議在具有 Hashbang 的腳本中使用 BOM。當您嘗試在 Unix/Linux 中運行腳本時,有 BOM 將不工作。因此,如果要直接從 shell 運行腳本,請使用沒有 BOM 的 UTF-8。您只能使用 #! 註釋樣式以指定 JavaScript 解釋器。在所有其他情況下,只需使用 // 註釋(或多行註釋)。
在 JavaScript 中使用 Unicode
十六進制
> 0x00A9 // 這是一個 16 進制數字
169 // 直接執行默認輸出為 10 進制
十六進制表示一個轉義序列
> '\xA9' // 一個字符通過 16 進製表示,或則説這裏兩個 16 進制所代表的字符通過 '\x' 轉義表示 ,最多支持兩個 16 進制
"©"
> '\xA9' === String.fromCodePoint(0xA9)
true
Unicode 轉義序列要求在 \\u 之後至少有四個字符(4 個 16 進制,代表兩個字節)
> '\u00A9' // \u 後面接 4 個 16 進制數表示一個字符轉義
"©"
Unicode 編碼轉義是 ECMAScript 6 新增特性。使用 Unicode 編碼轉義,任何字符都可以被轉義為十六進制編碼。最高可以用到0x10FFFF。
使用單純的 Unicode 轉義通常需要寫成分開的兩半以達到相同的效果。可以參考 String.fromCodePoint() 和 String.prototype.codePointAt() 。
'\u{2F804}' // 對於某些字符超出兩個字節表示的就得可以用 \u{} 包起對應的若干個 16 進制,不能超過 10FFFF
// 使用單純 Unicode 轉義
'\uD87E\uDC04' // 使用兩個 UTF-16 單元湊成一個 4 字節的字符碼點
不同字節字符表示方式
'\xA9' // 支持一個字節表示字符
'\u00A9' // 支持兩個字節表示字符
'\u{2F804}' // 支持兩個以上字節表示字符
兩個\\x 表示的字符無法拼接成一個雙字節的字符
> '\u01ff' // 雙字節字符
"ǿ"
> '\x01\xff' // \x01 是不可打印字符,相當於兩個字符串拼接
"ÿ"
兩個 \\u 表示的字符可以拼接成一個四字節的字符
// "𠮷" 在 UTF-16 是一個 4 字節字符 碼點是 20bb7
> "𠮷".charCodeAt(0) // 獲取前面兩個字節的 10 進制
55362
> "𠮷".charCodeAt(1) // 獲取後面兩個字節的 10 進制
57271
> (55362).toString(16) // 獲取對應的 16 進制
"d842"
> (57271).toString(16) // 獲取對應的 16 進制
"dfb7"
> '\ud842\udfb7'
"𠮷"
> "𠮷".codePointAt(0) // 獲取完整字符的 10 進制
134071
(134071).toString(16) // 獲取對應的 16 進制
"20bb7"
相關 API:
- str.charCodeAt
- str.codePointAt
- str.charAt
- String.fromCodePoint()
- String.fromCharCode
JavaScript 共有 6 種方法可以表示一個字符:
'\z' === 'z' // true
'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true
'\u{7A}' === 'z' // true
更多 ES-6 對 Unicode 的支持細節:
- ES6 - 字符的 Unicode 表示法
- String.fromCodePoint()
ASCII 碼錶參考
| Bin(二進制) | Oct(八進制) | Dec(十進制) | Hex(十六進制) | 縮寫/字符 | 解釋 | |
|---|---|---|---|---|---|---|
| 0000 0000 | 00 | 0 | 0x00 | NUL(null) | 空字符 | |
| 0000 0001 | 01 | 1 | 0x01 | SOH(start of headline) | 標題開始 | |
| 0000 0010 | 02 | 2 | 0x02 | STX (start of text) | 正文開始 | |
| 0000 0011 | 03 | 3 | 0x03 | ETX (end of text) | 正文結束 | |
| 0000 0100 | 04 | 4 | 0x04 | EOT (end of transmission) | 傳輸結束 | |
| 0000 0101 | 05 | 5 | 0x05 | ENQ (enquiry) | 請求 | |
| 0000 0110 | 06 | 6 | 0x06 | ACK (acknowledge) | 收到通知 | |
| 0000 0111 | 07 | 7 | 0x07 | BEL (bell) | 響鈴 | |
| 0000 1000 | 010 | 8 | 0x08 | BS (backspace) | 退格 | |
| 0000 1001 | 011 | 9 | 0x09 | HT (horizontal tab) | 水平製表符 | |
| 0000 1010 | 012 | 10 | 0x0A | LF (NL line feed, new line) | 換行鍵 | |
| 0000 1011 | 013 | 11 | 0x0B | VT (vertical tab) | 垂直製表符 | |
| 0000 1100 | 014 | 12 | 0x0C | FF (NP form feed, new page) | 換頁鍵 | |
| 0000 1101 | 015 | 13 | 0x0D | CR (carriage return) | 回車鍵 | |
| 0000 1110 | 016 | 14 | 0x0E | SO (shift out) | 不用切換 | |
| 0000 1111 | 017 | 15 | 0x0F | SI (shift in) | 啓用切換 | |
| 0001 0000 | 020 | 16 | 0x10 | DLE (data link escape) | 數據鏈路轉義 | |
| 0001 0001 | 021 | 17 | 0x11 | DC1 (device control 1) | 設備控制1 | |
| 0001 0010 | 022 | 18 | 0x12 | DC2 (device control 2) | 設備控制2 | |
| 0001 0011 | 023 | 19 | 0x13 | DC3 (device control 3) | 設備控制3 | |
| 0001 0100 | 024 | 20 | 0x14 | DC4 (device control 4) | 設備控制4 | |
| 0001 0101 | 025 | 21 | 0x15 | NAK (negative acknowledge) | 拒絕接收 | |
| 0001 0110 | 026 | 22 | 0x16 | SYN (synchronous idle) | 同步空閒 | |
| 0001 0111 | 027 | 23 | 0x17 | ETB (end of trans. block) | 結束傳輸塊 | |
| 0001 1000 | 030 | 24 | 0x18 | CAN (cancel) | 取消 | |
| 0001 1001 | 031 | 25 | 0x19 | EM (end of medium) | 媒介結束 | |
| 0001 1010 | 032 | 26 | 0x1A | SUB (substitute) | 代替 | |
| 0001 1011 | 033 | 27 | 0x1B | ESC (escape) | 換碼(溢出) | |
| 0001 1100 | 034 | 28 | 0x1C | FS (file separator) | 文件分隔符 | |
| 0001 1101 | 035 | 29 | 0x1D | GS (group separator) | 分組符 | |
| 0001 1110 | 036 | 30 | 0x1E | RS (record separator) | 記錄分隔符 | |
| 0001 1111 | 037 | 31 | 0x1F | US (unit separator) | 單元分隔符 | |
| 0010 0000 | 040 | 32 | 0x20 | (space) | 空格 | |
| 0010 0001 | 041 | 33 | 0x21 | ! | 歎號 | |
| 0010 0010 | 042 | 34 | 0x22 | " | 雙引號 | |
| 0010 0011 | 043 | 35 | 0x23 | # | 井號 | |
| 0010 0100 | 044 | 36 | 0x24 | $ | 美元符 | |
| 0010 0101 | 045 | 37 | 0x25 | % | 百分號 | |
| 0010 0110 | 046 | 38 | 0x26 | & | 和號 | |
| 0010 0111 | 047 | 39 | 0x27 | ' | 閉單引號 | |
| 0010 1000 | 050 | 40 | 0x28 | ( | 開括號 | |
| 0010 1001 | 051 | 41 | 0x29 | ) | 閉括號 | |
| 0010 1010 | 052 | 42 | 0x2A | * | 星號 | |
| 0010 1011 | 053 | 43 | 0x2B | + | 加號 | |
| 0010 1100 | 054 | 44 | 0x2C | , | 逗號 | |
| 0010 1101 | 055 | 45 | 0x2D | - | 減號/破折號 | |
| 0010 1110 | 056 | 46 | 0x2E | . | 句號 | |
| 0010 1111 | 057 | 47 | 0x2F | / | 斜槓 | |
| 0011 0000 | 060 | 48 | 0x30 | 0 | 字符0 | |
| 0011 0001 | 061 | 49 | 0x31 | 1 | 字符1 | |
| 0011 0010 | 062 | 50 | 0x32 | 2 | 字符2 | |
| 0011 0011 | 063 | 51 | 0x33 | 3 | 字符3 | |
| 0011 0100 | 064 | 52 | 0x34 | 4 | 字符4 | |
| 0011 0101 | 065 | 53 | 0x35 | 5 | 字符5 | |
| 0011 0110 | 066 | 54 | 0x36 | 6 | 字符6 | |
| 0011 0111 | 067 | 55 | 0x37 | 7 | 字符7 | |
| 0011 1000 | 070 | 56 | 0x38 | 8 | 字符8 | |
| 0011 1001 | 071 | 57 | 0x39 | 9 | 字符9 | |
| 0011 1010 | 072 | 58 | 0x3A | : | 冒號 | |
| 0011 1011 | 073 | 59 | 0x3B | ; | 分號 | |
| 0011 1100 | 074 | 60 | 0x3C | < | 小於 | |
| 0011 1101 | 075 | 61 | 0x3D | = | 等號 | |
| 0011 1110 | 076 | 62 | 0x3E | > | 大於 | |
| 0011 1111 | 077 | 63 | 0x3F | ? | 問號 | |
| 0100 0000 | 0100 | 64 | 0x40 | @ | 電子郵件符號 | |
| 0100 0001 | 0101 | 65 | 0x41 | A | 大寫字母A | |
| 0100 0010 | 0102 | 66 | 0x42 | B | 大寫字母B | |
| 0100 0011 | 0103 | 67 | 0x43 | C | 大寫字母C | |
| 0100 0100 | 0104 | 68 | 0x44 | D | 大寫字母D | |
| 0100 0101 | 0105 | 69 | 0x45 | E | 大寫字母E | |
| 0100 0110 | 0106 | 70 | 0x46 | F | 大寫字母F | |
| 0100 0111 | 0107 | 71 | 0x47 | G | 大寫字母G | |
| 0100 1000 | 0110 | 72 | 0x48 | H | 大寫字母H | |
| 0100 1001 | 0111 | 73 | 0x49 | I | 大寫字母I | |
| 01001010 | 0112 | 74 | 0x4A | J | 大寫字母J | |
| 0100 1011 | 0113 | 75 | 0x4B | K | 大寫字母K | |
| 0100 1100 | 0114 | 76 | 0x4C | L | 大寫字母L | |
| 0100 1101 | 0115 | 77 | 0x4D | M | 大寫字母M | |
| 0100 1110 | 0116 | 78 | 0x4E | N | 大寫字母N | |
| 0100 1111 | 0117 | 79 | 0x4F | O | 大寫字母O | |
| 0101 0000 | 0120 | 80 | 0x50 | P | 大寫字母P | |
| 0101 0001 | 0121 | 81 | 0x51 | Q | 大寫字母Q | |
| 0101 0010 | 0122 | 82 | 0x52 | R | 大寫字母R | |
| 0101 0011 | 0123 | 83 | 0x53 | S | 大寫字母S | |
| 0101 0100 | 0124 | 84 | 0x54 | T | 大寫字母T | |
| 0101 0101 | 0125 | 85 | 0x55 | U | 大寫字母U | |
| 0101 0110 | 0126 | 86 | 0x56 | V | 大寫字母V | |
| 0101 0111 | 0127 | 87 | 0x57 | W | 大寫字母W | |
| 0101 1000 | 0130 | 88 | 0x58 | X | 大寫字母X | |
| 0101 1001 | 0131 | 89 | 0x59 | Y | 大寫字母Y | |
| 0101 1010 | 0132 | 90 | 0x5A | Z | 大寫字母Z | |
| 0101 1011 | 0133 | 91 | 0x5B | [ | 開方括號 | |
| 0101 1100 | 0134 | 92 | 0x5C | \ | 反斜槓 | |
| 0101 1101 | 0135 | 93 | 0x5D | ] | 閉方括號 | |
| 0101 1110 | 0136 | 94 | 0x5E | ^ | 脱字符 | |
| 0101 1111 | 0137 | 95 | 0x5F | _ | 下劃線 | |
| 0110 0000 | 0140 | 96 | 0x60 | ` | 開單引號 | |
| 0110 0001 | 0141 | 97 | 0x61 | a | 小寫字母a | |
| 0110 0010 | 0142 | 98 | 0x62 | b | 小寫字母b | |
| 0110 0011 | 0143 | 99 | 0x63 | c | 小寫字母c | |
| 0110 0100 | 0144 | 100 | 0x64 | d | 小寫字母d | |
| 0110 0101 | 0145 | 101 | 0x65 | e | 小寫字母e | |
| 0110 0110 | 0146 | 102 | 0x66 | f | 小寫字母f | |
| 0110 0111 | 0147 | 103 | 0x67 | g | 小寫字母g | |
| 0110 1000 | 0150 | 104 | 0x68 | h | 小寫字母h | |
| 0110 1001 | 0151 | 105 | 0x69 | i | 小寫字母i | |
| 0110 1010 | 0152 | 106 | 0x6A | j | 小寫字母j | |
| 0110 1011 | 0153 | 107 | 0x6B | k | 小寫字母k | |
| 0110 1100 | 0154 | 108 | 0x6C | l | 小寫字母l | |
| 0110 1101 | 0155 | 109 | 0x6D | m | 小寫字母m | |
| 0110 1110 | 0156 | 110 | 0x6E | n | 小寫字母n | |
| 0110 1111 | 0157 | 111 | 0x6F | o | 小寫字母o | |
| 0111 0000 | 0160 | 112 | 0x70 | p | 小寫字母p | |
| 0111 0001 | 0161 | 113 | 0x71 | q | 小寫字母q | |
| 0111 0010 | 0162 | 114 | 0x72 | r | 小寫字母r | |
| 0111 0011 | 0163 | 115 | 0x73 | s | 小寫字母s | |
| 0111 0100 | 0164 | 116 | 0x74 | t | 小寫字母t | |
| 0111 0101 | 0165 | 117 | 0x75 | u | 小寫字母u | |
| 0111 0110 | 0166 | 118 | 0x76 | v | 小寫字母v | |
| 0111 0111 | 0167 | 119 | 0x77 | w | 小寫字母w | |
| 0111 1000 | 0170 | 120 | 0x78 | x | 小寫字母x | |
| 0111 1001 | 0171 | 121 | 0x79 | y | 小寫字母y | |
| 0111 1010 | 0172 | 122 | 0x7A | z | 小寫字母z | |
| 0111 1011 | 0173 | 123 | 0x7B | { | 開花括號 | |
| 0111 1100 | 0174 | 124 | 0x7C | \ | 垂線 | |
| 0111 1101 | 0175 | 125 | 0x7D | } | 閉花括號 | |
| 0111 1110 | 0176 | 126 | 0x7E | ~ | 波浪號 | |
| 0111 1111 | 0177 | 127 | 0x7F | DEL (delete) | 刪除 |
補充:
- 字體編輯用中日韓漢字Unicode編碼表