首頁 > 運動

【創投行聚焦】為什麼是0?為什麼是0??你所不知道的投資真相!

由 程式設計俠 發表于 運動2021-05-28

簡介UTF-16對於 Unicode 編號範圍在 0 ~ FFFF 之間的字元,UTF-16 使用兩個位元組儲存,並且直接儲存 Unicode 編號,不用進行編碼轉換,這跟 UTF-32 非常類似

65536為什麼是0

鄰桌手指在鍵盤上飛舞,忽然他抬起頭很嚴肅地問我:一個漢字編碼佔用幾個位元組?我頭也不抬很肯定的回答:兩個!直到他連續重複問了三遍,我才發現有點不對勁,猶豫了下回答到:應該是兩個吧。他笑了,笑聲讓我感到恐懼,一個入行級的問題問得我毫無自信,頭皮發麻。於是,帶著疑問好好梳理了下這個問題,結果發現自己被打臉!

【創投行聚焦】為什麼是0?為什麼是0??你所不知道的投資真相!

被打臉

先給出一種答案:中文在不同編碼是不定長的 2~4個位元組。

為什麼需要編碼

編碼?剛入行的小夥伴可能會有一連串小問號,為什麼需要編碼?直接使用漢字或者數字或者英文字元不行嗎?工欲善其事必先利其器,我們就先來介紹一下計算機中為什麼需要編碼。當今世界上共有233個國家和地區,其中包括197個國家和36個地區,這麼多國家和地區,自然就有很多的語言,表達這些語言的符號就有很多,如果計算機全部採用這些這些符號,那計算機的壓力就十分的巨大,而且要表達的符號太多,也無法簡單地使用一個位元組來表示。考慮到這些問題,借鑑多國之間語言存在差異,但是依然可以透過翻譯來暢談無阻,計算機也可以約定一套翻譯的規則,在於計算機通訊時,進項翻譯,這個過程,可以理解為編碼,編碼之後又可以解碼,還原成原來的內容。明白了這些之後,接下來就是了解有哪些編碼規則,以及他們之間有什麼區別。

常見的編碼方式

【創投行聚焦】為什麼是0?為什麼是0??你所不知道的投資真相!

常見的編碼方式

(1)ASCII編碼

美國製定的一套字元編碼,ASCII碼一共規定了128個字元的編碼。在計算機內部,資訊都可以表示成一個二進位制的字串。每一個二進位制位(bit)有0和1兩種狀態,因此八個二進位制位就可以組合出256種狀態,這被稱為一個位元組(byte)。也就是說,一個位元組一共可以用來表示256種不同的狀態,每一個狀態對應一個符號,就是256個符號,從00000000到11111111。

ASCII

GB2312是由中國國家標準總局1980年釋出的,1981年5月1日開始實施的一套國家標準,標準號是GB 2312—1980。GB2312編碼適用於漢字處理、漢字通訊等系統之間的資訊交換,每個漢字及符號以兩個位元組來表示,但他不夠全面,基本集共收入漢字6763個和非漢字圖形字元682個,有一些罕見字並未收錄,這就出現了後面的GBK及GB 18030。

GBK全稱《漢字內碼擴充套件規範》,又稱國標碼,1995年12月1日製訂的,GBK是採用單雙位元組變長編碼,英文使用單位元組編碼,完全相容ASCII字元編碼,中文部分採用雙位元組編碼。共收錄了21003個漢字。目前依然有一部分專案採用的是GBK編碼。

GB18030,全稱《資訊科技中文編碼字符集》,是中華人民共和國國家標準所規定的變長多位元組字符集。其對GB 2312-1980完全向後相容,與GBK基本向後相容,並支援Unicode(GB 13000)的所有碼位。GB 18030共收錄漢字70,244個。GB 18030採用變長多位元組編碼,每個字可以由1個、2個或4個位元組組成,他也是完全支援Unicode字符集的。

編碼

(2)GB2312/GBK/GB18030編碼

Unicode 也叫萬國碼,Unicode 是一個標準,嚴格意義上定位的是字符集,Unicode 字符集為每一個字元分配一個編號,透過這個編號就能找到對應的字元。從這個定義也可以看出,Unicode 只是對各個語言字元進行了編號,並沒有約定對編號如何儲存以及儲存幾個位元組等,而這些是由Unicode 字符集實現格式來約定的,比如下面提到的UTF-8、UTF-16、UTF-32等。

(2)

(3)

UTF-8是Unicode編碼的具體實現方式之一。它最主要的優點就是可變長度,字元編碼通常由 1-4 個位元組來表示,相比定長的實現方式,能夠節省更多的空間。除此之外,UTF-8 相容 ASCII,而Unicode的其他兩種方式UTF-32 和 UTF-16 都不相容 ASCII,因為它們沒有單位元組編碼。

(3)

Unicode字符集

UTF-32是Unicode編碼的具體實現方式之一。一種固定長度的編碼方案,不管字元編號大小,始終使用 4 個位元組來儲存;

(4)

UTF-16是Unicode編碼的具體實現方式之一。它介於 UTF-8 和 UTF-32 之間,使用 2 個或者 4 個位元組來儲存,長度既固定又可變。為什麼說是既固定又可變呢?UTF-16對於 Unicode 編號範圍在 0 ~ FFFF 之間的字元,UTF-16 使用兩個位元組儲存,並且直接儲存 Unicode 編號,不用進行編碼轉換,這跟 UTF-32 非常類似。對於 Unicode 編號範圍在 10000~10FFFF 之間的字元,UTF-16 使用四個位元組儲存。 UTF-16沒有指定字尾,即不知道其是大小端,所以其開始的兩個位元組表示該位元組陣列是大端還是小端。即FE FF表示大端,FFFE表示小端。故而又有兩種細化的編碼方式UTF-16BE和UTF-16LE。

UTF-16BE:其後綴是 BE 即 big-endian,大端的意思。大端就是將高位的位元組放在低地址表示。

UTF-16LE:其後綴是 LE 即 little-endian,小端的意思。小端就是將高位的位元組放在高地址表示。

漢字到底佔用幾個位元組

可能有人會問,一個漢字佔用幾個位元組為什麼會衍生出上面那麼多問題,正是因為使用不同的編碼方式可能佔用的位元組數就不一樣了。瞭解了編碼方式之後就比較容易有一個清晰的概念。

中文在不同編碼是不定長的 2~4個位元組(至少兩個位元組,由漢字的總數超過6萬字,2^16=65536)

(1) GBK編碼,一個漢字佔

(4)

位元組。

(2) UTF-16編碼,通常漢字佔

UTF-8編碼

位元組,CJKV擴充套件B區、擴充套件C區、擴充套件D區中的漢字佔四個位元組(一般字元的Unicode範圍是U+0000至U+FFFF,而這些擴充套件部分的範圍大於U+20000,因而要用兩個UTF-16)。

(3) UTF-8編碼是變長編碼,通常漢字佔

(5)

位元組,擴充套件B區以後的漢字佔四個位元組。

透過程式來試驗一下:

【創投行聚焦】為什麼是0?為什麼是0??你所不知道的投資真相!

獲取編碼位元組長度

控制檯輸出

【創投行聚焦】為什麼是0?為什麼是0??你所不知道的投資真相!

控制檯列印結果

按照上面的執行結果,“你”在UTF-16編碼下佔用4個位元組。那麼猜測兩個漢字“你好”,在UTF-16編碼下應該是8個位元組,但是執行結果卻和想象中的不一樣,“你好”在UTF-16編碼下共佔6個位元組。

執行結果好像和上面講到的有點不相符啊!為什麼會出現這樣的結果的?

原因:java的位元組碼檔案(。class)檔案採用的是UTF-8編碼,但是在java 執行時會使用UTF-16編碼。在轉碼的時候會在前面加上表示位元組順序的字元,這個字元稱為”零寬度非換行空格”(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。FEFF佔用兩個位元組,所以就解釋了為什麼java環境下在UTF-16編碼下,第一個漢字佔4個字元,後面每個佔用2個字元。

我們不妨將這些字元的在不同編碼下的二進位制轉換為16進位制並打印出來。將程式碼修改如下:

【創投行聚焦】為什麼是0?為什麼是0??你所不知道的投資真相!

控制檯輸出:

【創投行聚焦】為什麼是0?為什麼是0??你所不知道的投資真相!

透過對比之後,大家是不是有一個更加清晰的認識了呢?介紹完編碼的這些知識,下次如果有人再問你同樣的問題,我們就可以反問了:你說的是在哪種編碼條件下呢

Tags:位元組編碼UTFUnicode16