UTF8和GBK編碼互轉(zhuǎn)實現(xiàn)解析
基本知識
UTF8 本質(zhì)是 Unicode 標準的一種實現(xiàn)方式,UTF8 編碼和 Unicode 字符碼是有相互轉(zhuǎn)換的規(guī)則的。GBK 碼與 Unicode 字符碼是沒有設計有規(guī)律的對應關系的,即沒有相互轉(zhuǎn)換的規(guī)則。所以想要實現(xiàn) UTF8 和 GBK 編碼互轉(zhuǎn)需要依靠查表法,即 UTF8 轉(zhuǎn) GBK 編碼需要先按規(guī)則轉(zhuǎn)換成 Unicode 字符碼,再通過查表獲取該 Unicode 字符碼對應的 GBK 碼,同樣的 GBK 轉(zhuǎn) UTF8 編碼也需要先查表獲取對應的 Unicode 字符碼,再按照規(guī)則轉(zhuǎn)換成 UTF8 編碼。
獲取 GBK 和 Unicode 的編碼對應表
這里介紹兩個編碼對應表,分別是 CP936 編碼表,和漢字 Unicode 編碼表,包含的漢字都是基本漢字,一共 20902 個。除去 ASCII 字符外,這些編碼中包括的漢字都是兩個字節(jié)的長度。 其中 CP936 編碼表是按照遞增的 GBK 編碼值為索引的,對應值是 Unicode 編碼,(由于 GBK 的編碼并不是連續(xù)的,所有索引之間往往有空缺),而漢字 Unicode 編碼表是以遞增的 Unicode 漢字字符碼為索引的,對應值是 GBK 編碼(Unicode 編碼范圍 4E00-9FA5) 。
實現(xiàn)互轉(zhuǎn)
在獲取編碼表之后,想要實現(xiàn) GBK 和 Unicode 互轉(zhuǎn)的功能就沒有什么難度了,最簡單的方法就是定義一個編碼數(shù)組包含 GBK 和 Unicode 的映射關系,然后對所需要轉(zhuǎn)換的編碼進行查表,獲取對應編碼再拼接成一個數(shù)據(jù)串就完成了。
采用 CP936 編碼表:
需要定義一個 short 型二維數(shù)組存放 GBK 和 Unicode 的映射關系(因為 GBK 編碼值不是遞增的,中間有很多未使用的值),無論是 GBK 轉(zhuǎn) Unicode 還是 Unicode 轉(zhuǎn) GBK 使用時最長需要遍歷整個數(shù)組。
采用漢字 Unicode 編碼表:
需要定義一個 short 型一維數(shù)組,存放從 4E00-9FA5 直接的漢字字符,Unicode 的編碼字符減去 4E00 既是一維數(shù)組的索引。在 Unicode 轉(zhuǎn) GBK 時可以直接計算出對應 GBK 的索引值,直接獲取該編碼值即可。在 GBK 轉(zhuǎn) Unicode 的時候最長需要遍歷整個數(shù)組。
明顯可以看出來,使用漢字 Unicode 編碼表的時間復雜度和空間復雜度是低于使用 CP936 編碼表的,不做優(yōu)化的話,這里肯定選擇漢字 Unicode 編碼表。
優(yōu)化占用空間
缺點:
上面雖然實現(xiàn)了 GBK 和 Unicode 的互相轉(zhuǎn)換,但是在程序里面定一個 20902 長度的 short 數(shù)組還是太臃腫了,而且在某些情況嵌入式系統(tǒng)中是不允許定義這么多的。
優(yōu)化:
這里我們可以把編碼表改造成字庫文件。在帶操作系統(tǒng)的環(huán)境下以讀取文件的方式來讀取字符編碼。在嵌入式系統(tǒng)中沒有文件系統(tǒng)的環(huán)境下,我們可以把字庫文件燒入 Flash,以讀取 Flash 的方式來讀取字符編碼。
制作字庫文件:
漢字 Unicode 編碼表制作字庫文件并不復雜,新建一個 .txt 文件(以 ANSI 格式打開),將 Unicode 4E00-9FA5 對應的 GBK 編碼依次復制到文件中保存,修改名字為 GBK.bin 就可以了。(這里 GBK.bin 是沒有文件頭和校驗值的,直接按照索引讀取就行,需要注意的事這里不能有換行符)
優(yōu)化查找編碼速度
缺點:
使用 GBK.bin 優(yōu)化了程序占用的空間,但是 GBK 轉(zhuǎn) Unicode 的時候最長仍需要遍歷整個字庫文件,而且有一部分常用的字符是在 4E00-9FA5 后段部分的,這就導致了很多情況下查找效率的降低。
優(yōu)化:
漢字 Unicode 編碼表是根據(jù) Unicode 排序的,CP936 編碼表是根據(jù) GBK 排序的,我們可以將 CP936 編碼表也制作成字庫 CP936.bin,在 GBK 轉(zhuǎn) Unicode 的時候使用字庫 CP936.bin,在 Unicode 轉(zhuǎn) GBK 時使用 GBK.bin,這樣互轉(zhuǎn)都是按照編碼索引轉(zhuǎn)換成字庫索引直接讀取對應字庫,就省去了遍歷的過程。
制作字庫文件:
CP936 編碼表中的一部分 GBK Unicode 0x81FD 0x4FA1 0x81FE 0x4FA2 0x8240 0x4FA4 0x8241 0x4FAB
如上所示,GBK 的索引是不連續(xù)的,81FE 后面接的是 8240,實際上整個 CP936 中類似于此的斷層大概有一百多處,每處缺少的數(shù)目是不一樣的,這里我們可以通過編寫程序?qū)⑵溲a全索引,對于的 Unicode 的值設置成 0000,并寫入 GBK.bin 文件(這里對于大的斷層我們進過濾,并在后面的索引計算中進行特殊處理,以免補出來的 bin 文件過大)。
優(yōu)化字串轉(zhuǎn)換速度
上面都是單個編碼去計算索引,讀取文件獲取編碼返回,在大量的字符串轉(zhuǎn)換的時候會有很多冗余的操作,我們可以進行流程上的優(yōu)化,把所有需要獲取的字符編碼先全部轉(zhuǎn)換成索引,然后在去字庫中一次將所有需要的內(nèi)容都讀出來統(tǒng)一返回,這樣減少了流程上的調(diào)用。
UTF8 和 Unicode 的互轉(zhuǎn)
GBK 和 Unicode 的互轉(zhuǎn)已經(jīng)實現(xiàn)了,剩下的就是 UTF8 和 Unicode 的轉(zhuǎn)換,這部分就有固定的轉(zhuǎn)換規(guī)則如下:
UTF8 編碼規(guī)則:如果只有一個字節(jié)則其最高二進制位為 0,如果是多字節(jié),其第一個字節(jié)從最高位開始,連續(xù)的二進制位值為 1,1 的個數(shù)決定了其編碼的字節(jié)數(shù),其余各字節(jié)均以 10 開頭。
// Unicode6.1定義范圍:0~10 FFFF // 20 0000 ~ 3FF FFFF 和 400 0000 ~ 7FFF FFFF 屬于 UCS-4,UTF8 現(xiàn)在已經(jīng)棄用了這部分內(nèi)容 --------------------------------------------------------------------------------- n | Unicode (十六進制) | UTF - 8 (二進制) --+-----------------------+------------------------------------------------------ 1 | 0000 0000 - 0000 007F | 0xxxxxxx 2 | 0000 0080 - 0000 07FF | 110xxxxx 10xxxxxx 3 | 0000 0800 - 0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx 4 | 0001 0000 - 0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx --------------------------------------------------------------------------------- // 以下部分棄用 5 | 0020 0000 - 03FF FFFF | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 6 | 0400 0000 - 7FFF FFFF | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx ---------------------------------------------------------------------------------
以上就是UTF8和GBK編碼互轉(zhuǎn)實現(xiàn)解析的詳細內(nèi)容,更多關于UTF8 GBK編碼互轉(zhuǎn)的資料請關注腳本之家其它相關文章!
相關文章
OpenAI?函數(shù)調(diào)用示例及功能入門教程
這篇文章主要為大家介紹了OpenAI?函數(shù)調(diào)用示例及功能入門教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06git-github 子模塊倉庫更新(git submodule)及git中submodule子模塊
這篇文章主要介紹了git-github 子模塊倉庫更新(git submodule)/git中submodule子模塊的添加、使用和刪除,使用子模塊后,不必負責子模塊的維護,只需要在必要的時候同步更新子模塊即可,需要的朋友可以參考下2023-03-03Web開發(fā)/設計人員應當知道的15個網(wǎng)站
建個好網(wǎng)站絕非易事,工欲善其事必先利其器。本文編譯了15個極其有用的網(wǎng)站,任何一位網(wǎng)站開發(fā)者或設計人員都應該收藏起來2011-05-05FedAvg聯(lián)邦學習FedProx異質(zhì)網(wǎng)絡優(yōu)化實驗總結(jié)
這篇文章主要為大家介紹了FedAvg聯(lián)邦學習FedProx異質(zhì)網(wǎng)絡優(yōu)化的實驗總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05