因爲計算機內部只能識別和處理二進制代碼,因此字符都必須按照必定的規則用一組二進制編碼來表示。html
在學習編碼以前,須要先了解一下 字符集與編碼的關係:
字符集(Character Set)是字符的集合,定義系統能處理哪些字符;編碼(Encoding)則規定這些字符在計算機內部的表示方式。web
目前,國際上廣泛採用的一種字符系統是7位二進制編碼的ASCII碼,它可表示10個十進制數碼、52 個英文大寫字母和小寫字母(A~Z, a~z)及必定數量的專用符號(如$、%、+、=等),共128個字符。爲了存入計算機,一般最高位補0,湊足1B。數據庫
在ASCII碼中,編碼值0~31爲控制字符,用於通訊控制或設備的功能控制;編碼值32~126共95個字符稱爲可印刷字符;編碼值127是DEL碼。瀏覽器
0~9的ASCII碼值爲48(0110000)~57(0111001),即去掉高3位,只保留低4位,正好是二進制形式的0-9。
因爲ASCII碼的侷限性,各國的語言不能完整地表示出來。因而對 ASCII 字符集作了拓展。服務器
目前採用 GB 2312-80標準 : 漢字+各類符號共7445個。用兩個字節表示一個漢字,每字節用七位碼。(1個漢字至關於兩個英文字符)app
規定:ASCII 值小於 127 的字符的意義與原來 ASCII 集中的字符相同,但當兩個 ASCII 值大於 127 的字符連在一塊兒時,就表示一個簡體中文的漢字。svg
爲了在解碼時操做的統一,在 ASCII 裏原本就有的數字、標點、字母都統一從新表示爲了兩個字節長的編碼,這就是常說的 「全角」 字符,而原來在 127 號如下的就叫 「半角」 字符。工具
輸入編碼學習
區位碼:94個區,每區94個位置。是4位十進制數,前2位是區碼,後2位是位碼。
國標碼:將十進制的區位碼轉換成十六進制數後,再在每字節上加上20H。國標碼兩字節的最高位都是0。
漢字內碼:爲了方便計算機區分中文字符和英文字符,將國標碼兩字節最高位都改成「1「,這就是漢字內碼。編碼
GBK 是對 GB2312 的一個擴展,兼容 GB2312,所以也兼容 ASCII,也是一個變長編碼方案。下面是一個簡介:
GBK 整體編碼範圍爲 8140-FEFE,首字節在 81-FE 之間,尾字節在 40-FE 之間,總計 23940 個碼位,共收入 21886 個漢字和圖形符號,其中漢字(包括部首和構件)21003 個,圖形符號 883 個。
GBK 是國家有關部門與一些信息行業企業等一塊兒合做推出的方案,但並未做爲國家標準發佈,只是一個事實上的標準,一個過渡方案,爲 GB18030 標準做的一個準備。
世界上各國都有不一樣的編碼方式,0—127 表示的符號依然都是同樣的,由於他們都兼容 ASCII 碼,但127以後的同一個二進制數字能夠被解碼成不一樣的符號。所以,要想打開一個文本文件,就必須知道它的編碼方式,不然用錯誤的編碼方式解讀,就會出現亂碼。
把全部語言都統一到一套編碼裏,且兼容 ASCII。
ASCII、GBK 等類編碼模式的字符集和編碼方式都是一一對應的,Unicode是字符集,UTF-32/ UTF-16/ UTF-8是三種字符編碼方案。
整個編碼可分爲兩個過程。首先,將程序中的字符根據字符集中的編號數字化爲某個特定的數值,而後根據編號以特定的方式存儲到計算機中。
編號就至關於 ASCII 碼中的 ASCII 值,它就是 Unicode 字符集中惟一表示某個字符的標識,在 Unicode 也稱做碼點(Code Point)。
碼點轉換成各類編碼,又涉及到編碼過程當中定長與變長兩種實現方式,UTF-32 就屬於定長編碼,即永遠用 4 字節存儲碼點,而 UTF-八、UTF-16 就屬於變長存儲,UTF-8 根據不一樣的狀況使用 1-4 字節,而 UTF-16 使用 2 或 4 字節來存儲碼點。
在 UTF-32 這種定長的編碼方式下就表示每 4 個子節一個斷句,那麼字符 A 的碼點 U+0041(二進制爲 1000001)被 UTF-32 編碼後就會變成以下形式存儲在計算機中:
00000000 00000000 00000000 01000001
它會將 4 個字節中空出的高位所有填充爲 0。這種表示的最大缺點是佔用空間太大,由於無論都大的碼點都須要四個字節來存儲,很是的佔空間,那麼如何突破這個瓶頸呢?變長方案應運而生。
UTF-8 屬於變長的編碼方式,它可使用1~4個字節表示一個符號,根據不一樣的符號而變化字節長度。使用的是高位保留的方式來區別不一樣變長,具體方式以下:
0
,後面7位爲這個符號的 Unicode 碼。所以對於英語字母,UTF-8 編碼和 ASCII 碼是相同的。n
字節的符號(n > 1
),第一個字節的前n
位都設爲1
,第n + 1
位設爲0
,後面字節的前兩位一概設爲10
。剩下的沒有說起的二進制位,所有爲這個符號的 Unicode 碼。Unicode符號範圍 | UTF-8編碼方式
(十六進制) | (二進制) |
---|---|
0000 0000-0000 007F | 0xxxxxxx |
0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
解碼 UTF-8 編碼也很簡單了,若是一個字節的第一位是 0,則這個字節單獨就是一個字符;若是第一位是1
,則連續有多少個 1,就表示當前字符佔用多少個字節,」醜」 有三個 1 表示佔三個字符,而後取出有效位便可。
Unicode 爲 Emoji 分配碼點。 Emoji 符號就是一個文字,它會被渲染爲圖形。
以上三種都是屬於文字的編碼,但在計算機中,還有相似圖片這種媒體資源。由於圖片的二進制編碼中包含有不少不可見字符,沒法用文本展現。
base64編碼是用來解決把不可打印的內容塞進可打印內容的需求的。好比把圖片存到數據庫,圖片數據歸根到底仍是一堆二進制串,用base64編碼後的顯示成的字符串就大大縮小的長度,能夠存到數據庫。
所謂Base64,就是:小寫字母a-z、大寫字母A-Z、數字0-九、符號"+"、"/"(再加上做爲墊字的"=",其實是65個字符)----做爲一個基本字符集。而後,其餘全部符號都轉換成這個字符集中的字符。
具體來講,轉換方式能夠分爲四步。
第一步,將每三個字節做爲一組,一共是24個二進制位。
第二步,將這24個二進制位分爲四組,每一個組有6個二進制位。
第三步,在每組前面加兩個00,擴展成32個二進制位,即四個字節。
第四步,根據下表,獲得擴展後的每一個字節的對應符號,這就是Base64的編碼值。
由於,Base64將三個字節轉化成四個字節,所以Base64編碼後的文本,會比原文本大出三分之一左右。
若是字節數不足三,則這樣處理:
1.二個字節的狀況:將這二個字節的一共16個二進制位,按照上面的規則,轉成三組,最後一組除了前面加兩個0之外,後面也要加兩個0。這樣獲得一個三位的Base64編碼,再在末尾補上一個"="號。
好比,"Ma"這個字符串是兩個字節,能夠轉化成三組000100十一、000101十、00010000之後,對應Base64值分別爲T、W、E,再補上一個"="號,所以"Ma"的Base64編碼就是TWE=。
2.一個字節的狀況:將這一個字節的8個二進制位,按照上面的規則轉成二組,最後一組除了前面加二個0之外,後面再加4個0。這樣獲得一個二位的Base64編碼,再在末尾補上兩個"="號。
好比,"M"這個字母是一個字節,能夠轉化爲二組000100十一、00010000,對應的Base64值分別爲T、Q,再補上二個"="號,所以"M"的Base64編碼就是TQ==。
在計算機內存中,統一使用Unicode編碼,當須要保存到硬盤或者須要傳輸的時候,就轉換爲UTF-8編碼。
瀏覽網頁的時候,服務器會把動態生成的Unicode內容轉換爲UTF-8再傳輸到瀏覽器。
要正確顯示HTML頁面,web瀏覽器必須知道頁面中使用的字符集。
<!-- html --> <meta charset="UTF-8"> <!-- xml --> <?xml version="1.0" encoding="UTF-8"?>
比較HTML和xml中的寫法:xml的寫法更加規範
指定了編碼,它所對應的字符集天然就指定了,編碼纔是咱們最終要關心的。
BOM=Byte Order Mark,「字節順序標識」。響應流中的開頭字節。
若是有 BOM,就能直接知道對應的編碼
缺省方式是以上幾種方式都失效時的兜底方案,沒有 BOM,沒有 header,沒有 meta,瀏覽器只好「蒙」一個編碼。
若是多方式並存,且給出的編碼信息不一致,一般按這樣的優先級來取捨:
BOM > 響應頭編碼 > 文檔內編碼聲明
在 HTML 中,某些字符是預留的,好比不能使用小於號(<
)和大於號(>
),這是由於瀏覽器會誤認爲它們是標籤。若是但願正確地顯示預留字符,咱們必須在 HTML 源代碼中使用字符實體(character entities)。
字符實體: // < & entity_name; // < 或 & entity_number; // <
考慮到 URI 在各類平臺間傳輸時的兼容性,URI 規範中規定只有 US-ASCII 字符集中的字符能夠直接出如今 URI 中。事實上,甚至 ASCII 自己的許多字符也不容許直接出如今 URI 中,有的也要轉義。URL 路徑中的中文須要轉義,具體編碼用的是 utf-8。
能夠直接使用的: 26 個大小寫字母,10 個數字,四個標點符號:-
,.
,_
,~
(「短橫」、「點號」、「下劃線」、「波浪線」)。其它的有的屬於保留字,用做爲分隔符(delimiters),它們有:
":" / "/" / "?" / "#" / "[" / "]" / "@" / "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
好比正斜槓「/」就是一個最經常使用的分隔符。若是想在 URL 中包含這樣符號,又不想它們被解析爲分隔符,就要對其轉義。其它的還有一些不能夠打印的字符也要轉義,好比「空格」等。
保留字符在不作分隔符或者具備特殊含義的時候是須要編碼的。若是使用了一些其餘文字和特殊字符,則須要經過編碼的方式來進行表示:
因爲 URI 在協議中只挑選了部分ASCII 字符,數字以及符號,那麼當須要表示不在這個範圍以內的符號,字符,或者該字符在 URI 中被用來分隔符等特殊用途時,就須要對這個字符進行%編碼。百分號編碼也能夠叫作URLEncode,其中的每個部分用【%XX】來表示,其中 XX 表示一個十六進制的數。
encodeURI 會將須要編碼的字符轉換爲 UTF-8
的格式。對於非轉義字符以及保留字符(;,/?:@&=+$#
)不會進行轉義。
// URL中包含中文 encodeURI('http://www.帥.com'); // http://www.%E5%B8%85.com // 值的內容爲特殊符號。值爲?& encodeURI('http://a.com?key=?&'); // "http://a.com?key=?&"
encodeURIComponent 會編碼全部的 URL 保留字:
encodeURIComponent('https://aotu.io/') // "https%3A%2F%2Faotu.io%2F" encodeURI('https://aotu.io/') // "https://aotu.io/"
在處理頁面跳轉、跟服務器端進行交互時, 凡涉及到對URI進行解析的、最好用encodeURIComponent進行編碼避免部分數據的丟失.