Unicode中UTF-8與UTF-16編碼詳解

概述

本文經由過程引見Unicode編碼以及對應的兩種編碼體式格局UTF-8和UTF-16,讓讀者能夠相識關於字符串編碼的相干學問,同時能夠弄清楚Unicode和UTF-8和UTF-16之間的關聯。

本文的主要內容為:

  • Unicode編碼,包含Unicode編碼基本學問以及與UTF-8和UTF-16這兩種編碼體式格局的關聯
  • UTF-8編碼,包含基本觀點和Unicode編碼轉換到UTF-8編碼體式格局
  • UTF-16編碼,包含基本觀點和Unicode編碼轉換到UTF-16編碼體式格局
  • JavaScript中string與DOMString

本文作為utfx.js源碼剖析的基本學問貯備文章,經由過程相識UTF-8和UTF-16這兩種編碼體式格局,讀者能夠明白運用JavaScript舉行編碼轉換的道理。

假如想相識編碼轉換的運用場景,能夠瀏覽我之前的博客WebSocket系列之JavaScript字符串怎樣與二進制數據間舉行相互轉換

假如想相識utfx.js相干的源碼內容,能夠關注我的後續文章。

Unicode編碼

觀點

Unicode(
一致碼、萬國碼、單一碼)是計算機科學範疇里的一項業界規範,包含字符集、編碼方案等。Unicode 是為相識決傳統的字符編碼方案的局限而發生的,它為每種言語中的每一個字符設定了一致而且唯一的
二進制編碼,以滿足跨言語、跨平台舉行文本轉換、處置懲罰的請求。1990年最先研發,1994年正式宣布。

一般Unicode編碼是經由過程2 Byte來示意一個字符的,如U+A12B,2 Byte的二進制示意要領效果就是1010(A)0001(1) 0010(2)1011(B)

簡樸引見完了Unicode,我們來看下UTF-8和UTF-16。須要注重的是:UTF是Unicode TransferFormat的縮寫,UTF-8和UTF-16都是把Unicode碼轉換成遞次數據的一種編碼體式格局。

UTF-8

觀點

UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字符編碼,又稱萬國碼。由Ken Thompson於1992年建立。如今已規範化為RFC 3629。UTF-8用1到6個字節編碼Unicode字符。用在網頁上能夠一致頁面顯現中文簡體繁體及別的言語(如英文,日文,韓文)。

經由過程上面的引見我們能夠曉得,UTF-8是一種異常通用的可變長字符編碼體式格局。

起首,我們來引見下什麼叫做可變長編碼?可變長編碼就是指在針對某個字符舉行編碼時,他的示意長度是不牢固的。像UTF-8內里,ASCII所示意的字符集就是用1 Byte來示意,而大部份漢字則是用3 Byte來示意。

相較於Unicode一致運用2 Byte來示意字符,在碰到大部份字符都能夠用1 Byte示意時,能夠節約很多存儲空間。然則,假如碰到須要用凌駕2 Byte來示意的字符,那末UTF-8的編碼體式格局則會斲喪更多的存儲空間。

示意體式格局

經由過程上面的引見我們能夠曉得,差別的Unicode碼在UTF-8中佔用了差別的存儲空間。下面我們就經由過程一個表格來看下將Unicode字符轉換為UTF-8編碼體式格局的詳細步驟。个中的?示意轉換成UTF-8編碼后,Unicode碼佔用的二進制位置。

Unicode碼局限UTF-8編碼體式格局
U+0000~U+007F0????????
U+0080~U+07FF110????? 10??????
U+0800~U+FFFF1110???? 10?????? 10??????
U+10000~U+10FFFF11110??? 10?????? 10?????? 10??????

當我們獲得Unicode碼后,我們先依據上面的這個表推斷其所處的局限,然後將Unicode碼轉換為二進制示意,從后往前截取UTF-8編碼中所留為之長度,夙昔今後順次填入對應位置,所即可獲得UTF-8的編碼。我們舉兩個例子來看下:

  • U+0020,這個字符的小於0000 007F,所以只須要用1 Byte來舉行編碼。U+0020的二進制示意為0000(0)0000(0) 0010(2)0000(0),那末從后往前截取7位獲得010 0000,放入UTF-8編碼體式格局中,獲得的效果為00101111,轉換為十六進制獲得2F。因而存儲在內存中的的遞次就是2F
  • U+A12B,這個字符大於0000 0800,小於0000 FFFF,因而須要用3 Byte來舉行編碼。U+A12B的二進制示意為1010(A)0001(1) 0010(2)1011(B)。,那末從后往前截取16位獲得10100001 00101011(Unicode碼自身),放入UTF-8編碼中,獲得的效果為11101010 10000100 10101011,轉換十六進制獲得EA84AB。因而,存儲在內存中的遞次就是EA 84 AB

經由過程上面的例子,我置信人人對UTF-8的編碼有了一個深切的明白。下面,讓我們來看下另一種編碼體式格局——UTF-16。

UTF-16

觀點

UTF-16是
Unicode字符編碼五條理模子的第三層:字符編碼錶(Character Encoding Form,也稱為 “storage format”)的一種完成體式格局。即把Unicode字符集的籠統碼位映照為16位長的整數(即碼元, 長度為2 Byte)的序列,用於數據存儲或通報。Unicode字符的碼位,須要1個或許2個16位長的碼元來示意,因而這是一個變長示意。

援用維基百科中關於UTF-16編碼的詮釋我們能夠曉得,UTF-16起碼也會用2 Byte來示意一個字符,因而沒有辦法兼容ASCII編碼(ASCII編碼運用1 Byte來舉行存儲)。

示意體式格局

在UTF-16中,我們將Unicode分為了兩個局限,離別經由過程差別的體式格局舉行存儲。詳細示意見下圖。

Unicode局限UTF-16編碼體式格局
U+000~U+FFFF2 Byte存儲,編碼后即是Unicode值
U+10000~U+10FFFF 4 Byte存儲,現將Unicode值減去(0x10000),獲得20bit長的值。再將Unicode分為高10位和低10位。UTF-16編碼的高位是2 Byte,高10位Unicode局限為00x3FF,將Unicode值加上0XD800,獲得高位代辦(或稱為前導代辦,存儲高位);低位也是2 Byte,低十位Unicode局限一樣為0~0x3FF,將Unicode值加上0xDC00,獲得低位代辦(或稱為後尾代辦,存儲低位)

依據上面的轉換體式格局,我們就能夠將Unicode碼依據UTF-16的編碼體式格局舉行轉換。下面我們依然經由過程兩個例子來看下:

  • U+0020,這個值的局限在第一部份,即經由UTF-16編碼后,效果依然為U+0020,在內存中的遞次為00 20
  • U+12345, 這個值的局限在第二部份,因而須要先減去0x10000,獲得0x02345,拆分紅高10位00 0000 1000和低10位11 0100 0101。依據上面劃定規矩加上特定值后,高位代辦值為D808,低位代辦值為DF45,終究內存中的遞次為D8 08 DF 45

JavaScript中的string與DOMString

在JavaScript中,一切的string範例(或許被稱為DOMString)都是運用UTF-16編碼的。

因而,當我們須要轉換成二進制與後端舉行通訊時,須要注重相干的編碼體式格局。

總結

本文經由過程對Unicode編碼和UTF-8和UTF-16兩種編碼體式格局舉行引見,讓人人相識Unicode編碼以及相干的兩種遞次數據編碼體式格局。

本文是作為utfx.js源碼剖析的基本學問貯備文章,在稍後的時候將會給人人帶來相干內容的後續文章——utfx.js源碼剖析,讓人人能夠相識在JavaScript中怎樣舉行相干的編碼轉換。

    原文作者:hjava
    原文地址: https://segmentfault.com/a/1190000014324711
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞