UTF-8是如何編碼的?

衆所周知計算機上存儲的是二進制0和1,string字符串是如何轉變爲二進制0和1的呢?java

每個字符都會轉換爲對應的16進制,16進制也是一堆01代碼,就至關於存儲在計算機上的01代碼。git


不一樣的字符集經過不一樣的編碼方式存儲不一樣數目的字節數。下面以UTF-8是如何編碼存儲字符爲二進制的爲例子進行說明:github

String a = 「A」

a.getBytes().length is 1

byte array is [65]


String a = "ë"

a.getBytes().length is 2

byte array is [-61, -85]

如上所示: A字符佔用一個字節 ë字符佔用兩個字節。web

etBytes()假設默認編碼方式爲UTF-8。ui

一些字符是一個字節,一些字符是兩個字節,或者更多的字節,那麼如何進行解碼呢?this

UTF-8如何進行編碼?Wikipedia中給出了相關的規則:編碼

if the first byte starts with 0 then it is a single byte char翻譯

if the first byte starts with 110 then it is 2 bytescode

if the first byte starts with 1110 then it is 3 bytes圖片

if the first byte starts with 11110 then it is 4 bytes

if the first byte starts with 111110 then it is 5 byte

if the first byte starts with 1111110 then it is 6 byte

翻譯: 若是第一個字節以0開始,表明是一個單字節字符。 若是第一個字節以110開始,表明是雙字節字符。 若是第一個字節以1110開始,表明是三字節字符。 若是第一個字節以11110開始,表明是四字節字符。 若是第一個字節以111110開始,表明是五字節字符。 若是第一個字節以1111110開始,表明是六字節字符。

因此咱們解碼就是反推便可: if the first byte starts with 0 then it is a single byte char so it decodes only that byte

if the first byte starts with 110 then it is 2 byte so it decodes 2 consecutive bytes

if the first byte starts with 1110 then it is 3 byte so it decodes 3 consecutive bytes

if the first byte starts with 11110 then it is 4 byte so it decodes 4 consecutive bytes

if the first byte starts with 111110 then it is 5 byte so it decodes 5 consecutive bytes

if the first byte starts with 1111110 then it is 6 byte so it decodes 6 consecutive bytes

下面用表格的方式列出Unicode和16進制以及佔用字節之間的關係:

輸入圖片說明

實例實戰

ë

110 xxxxx 10 xxxxxx

110 00011 10 101011

00011       101011  → binary equivalent of hex pointing to ë

ɟ 110 xxxxx 10 xxxxxx

110 01001 10 011111

01001     011111   → binary equivalent of hex pointing to ɟ

11100000 10101101 10011111如何解碼? 1110表明是三個字節爲一個字符: 1110xxxx 10xxxxxx 10xxxxxx

11100000 10101101 10011111

so 0000 101101 011111 is the binary to be decoded.

因此爲 0000 101101 011111 每四位爲: 0000 1011 0101 1111 爲:B5F

The binary is B5F in hexadecimal (If you don't know to convert use this binary to hex converter website ) Now from map B5F means ୟ .


練習:對01000010 01000001 11000011 10110000 11100010 10001011 10110011進行解碼

一、第一個字符 01000010 爲一個字符: 0100 0010爲:42 參考這裏 對應字符B

二、第二個字符

01000001 爲一個字符: 0100 0001爲:41 參考表格 對應字符A

三、第三個字符 11000011 10110000 爲一個字符: 0000 11 110000 就是F0, 參考表格 映射爲字符:ð

四、第四個字符: 11100010 10001011 10110011 爲一個字符: 00010 001011 110011 就是 22F3 參考表格映射爲字符:⋳

結論就是:01000010 01000001 11000011 10110000 11100010 10001011 10110011 採用UTF-8編碼爲BAð⋳

String 的 getBytes("UTF-8")作了什麼操做呢?

String s = "ABCDEF⋳";

ABCDEF⋳經過getBytes("UTF-8")被編碼爲UTF-8格式,它是如何存儲的呢? A - 01000001

B - 01000010

C - 01000011

D - 01000100

E - 01000101

F - 01000110

⋳ - 11100010 10001011 10110011

注意:以上是以字節的形式存儲在內存中

因此getBytes("UTF-8")是獲取每個字節返回。

在內存中是如何存儲的呢?

01000001 表明正數 65 可是11100010 表明負數 -31

因此存儲在內存中爲: 01000001 - 65

01000010 - 66

01000011 - 67

01000100 - 68

01000101 - 69

01000110 - 70

11100010 - -31

10001011 - -117

10110011 - -77

代碼爲證:

String s = "ABCDEF⋳";
        	 byte[]  bs = s.getBytes("UTF-8");
        	 for(byte  b : bs)
        	 System.out.print(b+",");

輸出:

65,66,67,68,69,70,-30,-117,-77

Reference1 Reference2

相關文章
相關標籤/搜索