這個'?'字的轉換為什麼是這個結果(GBK和GB18030互轉)
http://www.itpub.net/thread-1164171-1-1.html
select convert('?','ZHS16GBK','ZHS32GB18030') A,
convert('?','ZHS32GB18030','ZHS16GBK') B,
convert('?','ZHS32GB18030','ZHS32GB18030') C,
dump('?') D,
dump(convert('?','ZHS32GB18030','ZHS32GB18030')) E
from dual;
-----結果如下---------------------------------------
A B C D E
? ?? ? Typ=96 Len=2: 254,159 Typ=1 Len=2: 254,159
資料庫、客戶端和作業系統字符集都是GBK,應用時發現這個字'?'從GB18030轉碼到GBK有問題,在這裡進行實驗。從編碼看兩個字符集這個字都有相同的編碼FE 9F,也就是254,159。
為什麼相互轉換的時候會變成‘?’和‘??’,我試過編碼在'?'字附近的一些其它字,發現編碼為FE XX的這個區,很多字都有這個轉換成問號的問題,能幫忙解釋一下這個問題是怎麼產生的嗎。
這個問題基本弄清楚了,解釋如下:
首先說字符集,GBK字符集有80個字元是後來增補的,因為需要與GB18030相容,所以放在GB18030的PUA區(此時這80個字元也在Unicode中有自己的對應的一套編碼了,這一套編碼在GB18030和GBK中的對映是一致的),後來這80個字元被Unicode字符集收錄,於是在Unicode中有了自己的第二套編碼,但是這第二套編碼是不被GBK所相容,僅GB18030可識別,這些字元的新編碼也叫非PUA編碼。
簡單說,這幾個字元從GBK到Unicode,對應編碼為A,從GB18030到Unicode,對應編碼為A和A',Oracle在轉換時選擇的就是轉為A',A'是轉不回GBK編碼的。這就是第一個'?出現'的原因。
做一個實驗可驗證:
select convert('?','ZHS16GBK','ZHS32GB18030') A,
convert(convert('?','UTF8','ZHS32GB18030'),'ZHS16GBK','UTF8') A1,
dump(convert('?','UTF8','ZHS32GB18030')) A2
from dual;
A A1 A2
-- -- ------------------------
? ? Typ=1 Len=3: 228,182,174
'?'字的Unicode的非PUA編碼是4DAE,換算成UTF8的編碼方式是11100100 10110110 10101110,剛好是228,182,174
而且從轉換結果看,我們有理由相信Oracle在進行convert時是把源字符集的字元先轉換到Unicode字符集,然後再轉換到目標字符集。
再做另一個實驗:
select
dump(convert('?','ZHS32GB18030','ZHS16GBK')) B,
dump(convert(convert('?','UTF8','ZHS16GBK'),'ZHS32GB18030','UTF8') )B1,
dump(convert('?','UTF8','ZHS16GBK')) B3
from dual;
B B1 B3
-------------------------- -------------------------- ------------------------
Typ=1 Len=4: 131,54,207,57 Typ=1 Len=4: 131,54,207,57 Typ=1 Len=3: 238,161,163
確實B和B1兩種轉換結果相同。另外對原貼中的'??'的解釋,我們從B3的結果看,從GBK轉換到UTF8時,轉換後的UTF8編碼對應的Unicode編碼為E863,轉換結果是正確的。而從E863轉換到GB18030時結果是131,54,207,57,這個換算後對應的編碼是8336 CF39,對應不到任何GB18030的字元,所以顯示'??',但具體131,54,207,57是如何產生的,我還沒有確切弄明白,可能是Oracle的BUG,也可能是對PUA區選擇的問題。
以下是那80個字以及對應的GBK編碼(GB18030編碼也相同),PUA編碼和非PUA編碼(這兩個是Unicode編碼)
漢字 GBK編碼 PUA編碼 非PUA編碼
? FE50 E815 2E81
? FE51 E816 20087
? FE52 E817 20089
? FE53 E818 200CC
? FE54 E819 2E84
? FE55 E81A 3473
? FE56 E81B 3447
? FE57 E81C 2E88
? FE58 E81D 2E8B
? FE59 E81E 9FB4
? FE5A E81F 359E
? FE5B E820 361A
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23590362/viewspace-1056221/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ppt轉pdf怎麼轉?試試這個轉換技巧!
- 怎麼獲取beego查詢的的結果,Students這個裡面的結果為啥是初始化的?Go
- Koala Framework是什麼?我為什麼要寫這個框架?Framework框架
- 為什麼這段程式碼輸入一個數之後顯示不了結果
- RFM是什麼?這個模型有什麼用?模型
- 這是什麼這是什麼
- 為什麼windows更換一個硬體就這麼難呢?Windows
- 這個一鍵分發平臺,為什麼這麼好用?
- C++ 這個語句中[&]是什麼意思C++
- DeepMind給AI模型做了個IQ測試,結果是這樣的AI模型
- 什麼是Transform轉換ORM
- php的漢字轉換: Unicode(UTF8)->GBK (轉)PHPUnicode
- JavaScript 加減危機 —— 為什麼會出現這樣的結果?JavaScript
- 這個用什麼模式模式
- golang中time型別的這個是什麼意思?Golang型別
- 這個問題的思考方向應該是什麼??????
- 為什麼資料和分析是數字化轉型的關鍵?
- 雲廠商為什麼都在衝這個KPI?KPI
- 什麼是資料轉換?
- 為什麼網路轉型是數字化轉型的基礎?
- Python是什麼?為什麼這麼搶手?Python
- 應用 poium 庫的測試結果 OK, 為什麼還會有 “send_keys element: undefined;” 這個 info??Undefined
- c++中utf8字串和gbk字串的轉換C++字串
- 程式設計師工資為什麼普遍很高,原來是因為這個...程式設計師
- iOS 時間轉換 datefromstring結果為niliOS
- 圖片轉換成文字怎麼轉?一鍵轉換看這裡
- Python為啥這麼火?兩個字:高薪!這套教程免費領!Python高薪
- 這個長得和 a 一模一樣,但是卻不是 a的字元是什麼字元
- 圖神經網路,這到底是個什麼?神經網路
- 來聊聊,這個Java到底是什麼東西?Java
- 為什麼程式設計師總是寫糟糕的程式碼?這3個原因程式設計師
- 特徵模型和特徵-這是什麼?特徵模型
- 這個原始碼是開源的麼原始碼
- 為什麼網頁Cookies用了曲奇餅乾這個詞?網頁Cookie
- 庫克為什麼選擇這個時候出櫃?
- 為什麼redis是單執行緒的以及為什麼這麼快?Redis執行緒
- 360行,行行轉前端:前端崗為什麼這麼火?這套教程限時領前端
- 揭秘|為什麼站長們愛將域名轉入GoDaddy,這樣做的原因是什麼?Go