簡述字符集與編碼

因爲計算機內部只能識別和處理二進制代碼,因此字符都必須按照必定的規則用一組二進制編碼來表示。html

在學習編碼以前,須要先了解一下 字符集與編碼的關係:
字符集(Character Set)是字符的集合,定義系統能處理哪些字符;編碼(Encoding)則規定這些字符在計算機內部的表示方式。web

image

字符編碼ASCII碼(編碼字符集)

目前,國際上廣泛採用的一種字符系統是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

GBK 是對 GB2312 的一個擴展,兼容 GB2312,所以也兼容 ASCII,也是一個變長編碼方案。下面是一個簡介:

GBK 整體編碼範圍爲 8140-FEFE,首字節在 81-FE 之間,尾字節在 40-FE 之間,總計 23940 個碼位,共收入 21886 個漢字和圖形符號,其中漢字(包括部首和構件)21003 個,圖形符號 883 個。

GBK 是國家有關部門與一些信息行業企業等一塊兒合做推出的方案,但並未做爲國家標準發佈,只是一個事實上的標準,一個過渡方案,爲 GB18030 標準做的一個準備。


世界上各國都有不一樣的編碼方式,0—127 表示的符號依然都是同樣的,由於他們都兼容 ASCII 碼,但127以後的同一個二進制數字能夠被解碼成不一樣的符號。所以,要想打開一個文本文件,就必須知道它的編碼方式,不然用錯誤的編碼方式解讀,就會出現亂碼。


Unicode

把全部語言都統一到一套編碼裏,且兼容 ASCII。

ASCII、GBK 等類編碼模式的字符集和編碼方式都是一一對應的,Unicode是字符集,UTF-32/ UTF-16/ UTF-8是三種字符編碼方案。

整個編碼可分爲兩個過程。首先,將程序中的字符根據字符集中的編號數字化爲某個特定的數值,而後根據編號以特定的方式存儲到計算機中。

編號就至關於 ASCII 碼中的 ASCII 值,它就是 Unicode 字符集中惟一表示某個字符的標識,在 Unicode 也稱做碼點(Code Point)

image

碼點轉換成各類編碼,又涉及到編碼過程當中定長變長兩種實現方式,UTF-32 就屬於定長編碼,即永遠用 4 字節存儲碼點,而 UTF-八、UTF-16 就屬於變長存儲,UTF-8 根據不一樣的狀況使用 1-4 字節,而 UTF-16 使用 2 或 4 字節來存儲碼點。

UTF-32

在 UTF-32 這種定長的編碼方式下就表示每 4 個子節一個斷句,那麼字符 A 的碼點 U+0041(二進制爲 1000001)被 UTF-32 編碼後就會變成以下形式存儲在計算機中:

00000000 00000000 00000000 01000001

它會將 4 個字節中空出的高位所有填充爲 0。這種表示的最大缺點是佔用空間太大,由於無論都大的碼點都須要四個字節來存儲,很是的佔空間,那麼如何突破這個瓶頸呢?變長方案應運而生。

UTF-8

UTF-8 屬於變長的編碼方式,它可使用1~4個字節表示一個符號,根據不一樣的符號而變化字節長度。使用的是高位保留的方式來區別不一樣變長,具體方式以下:

  1. 對於單字節的符號,字節的第一位設爲0,後面7位爲這個符號的 Unicode 碼。所以對於英語字母,UTF-8 編碼和 ASCII 碼是相同的。
  2. 對於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 表示佔三個字符,而後取出有效位便可。

Emoji

Unicode 爲 Emoji 分配碼點。 Emoji 符號就是一個文字,它會被渲染爲圖形。

Emoji編碼


以上三種都是屬於文字的編碼,但在計算機中,還有相似圖片這種媒體資源。由於圖片的二進制編碼中包含有不少不可見字符,沒法用文本展現。


Base64

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==。

轉換Base64工具
參考文章

計算機中通用的字符編碼的工做方式

在計算機內存中,統一使用Unicode編碼,當須要保存到硬盤或者須要傳輸的時候,就轉換爲UTF-8編碼。

瀏覽網頁的時候,服務器會把動態生成的Unicode內容轉換爲UTF-8再傳輸到瀏覽器。

Web 中的編碼

要正確顯示HTML頁面,web瀏覽器必須知道頁面中使用的字符集。

<!-- html -->
<meta charset="UTF-8">
​
<!-- xml -->
<?xml version="1.0" encoding="UTF-8"?>

比較HTML和xml中的寫法:xml的寫法更加規範

  • charset 是 character set 的簡寫,即字符集
  • encoding 是 charset encoding 的簡寫,即字符集編碼,簡稱編碼

指定了編碼,它所對應的字符集天然就指定了,編碼纔是咱們最終要關心的。

如何肯定一個網頁中編碼

  1. 文檔內的編碼聲明

    image

  2. 響應體中的content-type字段中的編碼信息

    image

  3. BOM

    BOM=Byte Order Mark,「字節順序標識」。響應流中的開頭字節。

    若是有 BOM,就能直接知道對應的編碼

    img

  4. 缺省

    缺省方式是以上幾種方式都失效時的兜底方案,沒有 BOM,沒有 header,沒有 meta,瀏覽器只好「蒙」一個編碼。

若是多方式並存,且給出的編碼信息不一致,一般按這樣的優先級來取捨:

BOM > 響應頭編碼 > 文檔內編碼聲明

HTML 編碼

在 HTML 中,某些字符是預留的,好比不能使用小於號(<)和大於號(>),這是由於瀏覽器會誤認爲它們是標籤。若是但願正確地顯示預留字符,咱們必須在 HTML 源代碼中使用字符實體(character entities)。

字符實體: // <
​
& entity_name; // &lt;
或
& entity_number; // &#60;

URI 編碼

編碼緣由:

考慮到 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進行編碼避免部分數據的丟失.

相關文章
相關標籤/搜索