webSocket 二進位制傳輸基礎準備-Unicode轉UTF16和UTF8

咕咕gu發表於2019-04-04

前言

今天學習一下編碼,先回顧一下昨天的基礎準備工作

下面進行了解UTF-8的二進位制編碼方式。

為啥要了解這個,因為js中所有是string型別都是使用UTF-16編碼的

因此我們與後端進行通訊時,需要轉換成與之一致的編碼。(後端或者前端轉換)

UTF-8編碼方式

:

1.  Unicode碼範圍 用十六進位制表示
2.  8位二進位制為一位元組
複製程式碼

UTF-8編碼方式

Unicode碼轉換UTF-8

完整的 Unicode 字符集 使用,轉換到UTF-8編碼 在Unicode中漢字 “一”編碼為U+4E00,"丁"編碼為 U+4E01這樣想必就看得懂表了 下面進行開始轉換吧 回顧昨日的二進位制與十六進位制

U+4E00用十六進位制表示 0x4E00
轉換二進位制,按位轉換
4 = 0100
E = 14 = 1110
0 = 0000
0 = 0000
0x4E00 = 0100 1110 0000 0000 = 19968
0x0800< 0x4E00 < 0xFFFF 得出是三個位元組。
UTF-8三位元組的編碼方式
從 0100 1110 0000 0000 變成 1110 xxxx 10 xxxxxx 10 xxxxxx格式
由從末位到首位進行順位插入的方式
     0100    111000    000000
1110 xxxx 10 xxxxxx 10 xxxxxx
1110 0100 10 111000 10 000000

其中利用js的按位操作符 符號操作符進行轉換
先替換原碼(從末位到首位)的第7位8位
第一位元組
utf-8 3位元組中的第一位元組格式 為 10 xxxxxx所有擷取6位(原碼與編碼對應的 為x的位值,要保持不變, 編碼其中的x位值全部為原碼)

先利用按位與的特性(全1為1 否則為0)進行擷取原碼的末6位

二進位制 111111 = 63十進位制

0100 1110 0000 0000 & 0000 0000 0011 1111 = 000000
19968 & 63  =  000000

UTF-8的第一位元組格式為 10 xxxxxx所以利用按位或的特性(遇1為1,全0 為0)來變換UTF-8 3位元組中的第一個位元組的編碼方式
將x替代為0 得出 10 000000
二進位制 10 000000 = 128;
按位或
00 000000 | 10 000000 = 10 000000
0 | 128 = 128

第二個位元組
UTF-8 3位元組中的第二位元組依然是10 xxxxxx格式,所以只需要從第6位開始進行擷取6位
利用帶符號右移操作符 a >> b  首位開始補 b 個 首位值  右側捨去b個位
先捨去末6位
0100 1110 0000 0000 >> 6 = 000 000 0100 1110 00
19968 >> 6 = 312

利用按位與進行擷取
000 000 0100 1110 00 & 111111  = 111 000
312 & 63 = 56

繼續利用按位或進行變換
00 111000 | 10 000000 = 10 111000
56 | 128 = 184

第三位元組
utf-8 3位元組的第三位元組編碼方式為 1110 xxxx 所以只需要從第12開始擷取4位
從末位第12位開始擷取4位,利用帶符號右移操作符 a >> b  首位開始補 b 個 首位值  右側捨去b個位
0100 1110 0000 0000 >> 12 = 000 000 0000 0100
19968 >> 12 = 4
利用按位與進行擷取 4位
二進位制 1111 = 15
0100 & 1111 = 0100
4 & 15 = 4;
利用按位或進行變換
二進位制 1110 0000 = 224
0000 0100 | 1110 0000 =  1110 0100
4 | 224 = 228

三個位元組組合起來
228 184 128  = 1110 0100 1011 1000 1000 0000(二進位制) = 14 4 11 8 8 0( 四位轉一位十進位制) =0xe4b880(十六進位制)
Unicode轉utf-8
0x4E00 = 0xe4b880

python編碼轉換
b'\xe4\xb8\x80'.decode('utf-8') = "一"
複製程式碼

UTF-16編碼方式

相對於來說比UTF8編碼就簡單了許多

UTF-16編碼方式

Unicode轉UTF-16

今天使用 U+22222(大於U+10000) 進行轉碼UTF16


先進行減去0x10000
0x22222 - 0x10000 = 0x12222 =  1 0010 0010 0010 0010
轉換二進位制並且分割位高低10位
二進位制1111111111 =  1023十進位制
利用按位與的特性獲取低10位
二進位制1111111111  &  1 00100010 00100010 = 10 0010 0010
十進位制1023 & 0x12222 =  546
低10位加0xDC00
546 + 0xDC00 =  56866 = 0xde22

利用帶符號右移運算子以及按位與獲取高10位

0x12222 << 10 = 72 = 1001000
1001000 & 1111111111 = 1001000
72 & 1023  = 72
高10位加0xD800
72 + 0xD800 = 55368 = 0xd848

U+22222編碼轉UTF-16 = [0xd848,0xde22]
var  str = "";
[0xd848,0xde22].forEach(item => {
    str +=String.fromCharCode(item)
})
console.log(str);

複製程式碼

明天就是假期了,儘可能的做出UTF-16與UTF-8 的互轉。 大概原理就是先將 字元 逆推轉為Unicode編碼格式 然後再轉你想要的編碼格式

若有不足,多望指正。 畢竟也是才接觸學習了兩天。

相關文章