作者pkmu8426 (巴426)
看板C_Sharp
標題[問題] GBK轉編碼
時間Tue Jun 17 11:24:08 2014
各位先進好,
目標字(範例): 蹈桶狟婥
我測了一些方式, 想把這串GBK編碼的文字轉成可識別的中文, 無論是簡或繁。
目前已知
1. .Net中任何String的表示形式 都是Unicode
2. System.text.Encodng class提供一些 API可以轉
3. 轉換時要指定輸入編碼 輸出編碼, 並一律以byte[]形式進行轉換
相關語法
ex. Encoding.getEncoding("編碼").getbytes(string) (轉成byte[])
Encoding.convert(原編碼,目標編碼, 要轉的byte[]) (轉成byte[])
Encoding.getEncoding("編碼").getString(byte[]) (轉成string)
等等...
我做了各種測試 但是找不到正確的用法把GBK文字轉成中文
頂多show出的結果是原來的GBK目標字而不是亂碼。
不曉得原因為何?
如果是.NET不支援GBK, 但我測試過 下面這行
StreamReader(path + ".txt",Encoding.GetEncoding("GBK"));
編碼卻是轉換成功的, 可以正確顯示中文。
請問有人知道怎解嗎? 謝謝。
--
人生 何必
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 122.118.23.78
※ 文章網址: http://webptt.com/m.aspx?n=bbs/C_Sharp/M.1402975455.A.3AA.html
1F:→ pkmu8426:不好意思 補充一下 官方語法我有測過, 也都是byte[]時轉 06/17 15:37
2F:→ pkmu8426:轉出來的結果卻是失敗@ @ 06/17 15:37
3F:→ pkmu8426:有按照相對應的碼去接和解 用法應該是沒用錯 06/17 15:39
4F:推 Litfal:答:列表下载 06/17 17:07
5F:→ Litfal:你一定想反了。 06/17 17:08
6F:→ Litfal:你想想你最後是因為哪個decode才拿到錯的字串?再反推回去 06/17 17:21
7F:→ Litfal:就會得到答案了。 06/17 17:21
抱歉 不是很能理解... 我原不想把語法貼上來 因為可能是錯的
但不貼上來 可能大家也不知道錯在哪 我下面貼一下。
string s = "蹈桶狟婥";
//轉成GBK byte[]
byte[] gbk_byte = Encoding.GetEncoding("gbk").GetBytes(s.ToString());
//轉成UTF8 byte[]
byte[] utf8_byte =
Encoding.Convert(Encoding.GetEncoding("gbk"), Encoding.UTF8, gbk_byte);
//轉成顯示字串
string text = Encoding.UTF8.GetString(utf8_byte);
初步想法是這樣 請問哪邊是該修正的? 謝謝
8F:→ Litfal:我就說反了吧XD,你是把GBK編碼的文件,用其他編碼器decode 06/17 21:18
9F:→ Litfal:這時就已經變錯的字了。 06/17 21:19
10F:→ Litfal:以你的狀況,就是拿BIG5解了GBK的Binary,所以拿到錯的字 06/17 21:29
11F:→ Litfal:所以要反過來用BIG5編那串錯的字,拿回原始的Binary。 06/17 21:33
12F:→ Litfal:再拿原始的Binary用正確的GBK encoding解成文字。 06/17 21:34
13F:→ Litfal:但要注意,如果在錯誤的BIG5解時拿到 ? (沒有對照的字)那這 06/17 21:35
14F:→ Litfal:樣也是轉不回來的。 06/17 21:35
謝謝回覆 @ @
我想請問 怎麼知道是Big5?? 我想過可能Win7系統Default可能是UTF8之類
卻怎樣也沒想過朝Big5去想 是Compiler的環境? 或者是我抓的目標本身是Big5..
光從字串就可以看出是Big5編的亂碼..
另外所謂的Binary 如果要轉的字串來源
如本篇 String s = ""; 直接就是宣告在程式中了 那做法也是一樣用Big5去解?
其實我看得懂你的意思 簡單說就是我以為的編碼 卻不只是我以為的。
只是不太懂 明明照API的參數去call 我以為是對 但其實卻錯了(?) 冒出個Big5
(然後我一直有想到是否該轉回Unicode 再繼續做進一步的轉換。 就是沒想到Big5)
如果問題簡化一點 純粹就是宣告在程式中的String 只是內容是GBK,
這樣做法會不會不一樣??
拍謝問了這麼多 .. 我再努力做看看 謝謝。
※ 編輯: pkmu8426 (122.118.23.78), 06/17/2014 21:54:48
15F:推 watermark001:目前windows系列編碼都是GB編碼~ 06/17 23:21
16F:→ Litfal:.net的string就是string,雖然他在記憶體中是unicode,但 06/18 00:32
17F:→ Litfal:我不建議把編碼的概念和string混淆,把它想的最單純--就是 06/18 00:32
18F:→ Litfal:個string就對了。 06/18 00:33
19F:→ Litfal:只有二進位和String互相轉換時,才該想到編碼。 06/18 00:34
20F:推 ideaup:蹈桶狟婥==列表下載 06/18 11:08
21F:推 nfsong:推 06/18 12:41
22F:→ ssccg:string就是string沒有編碼,所謂編碼是把string表示成byte時 06/18 13:54
23F:→ ssccg:的數值,如"列"在GB是C1D0,在Big5是A643,UTF8是E58897 06/18 14:20
24F:→ ssccg:"蹈"在Big5是C1D0,不是"蹈桶狟婥"內容是GBK,而是當初把 06/18 14:41
25F:→ ssccg:"列表下载"用GBK編碼成C1D0....,然後再用Big5解碼的結果 06/18 14:44
26F:→ ssccg:這單純是編解碼的問題,跟轉碼沒有關係 06/18 14:47
27F:→ ideaup:將(蹈桶狟婥)以ansi 格式儲檔, 讀取為bytes[],再處理 06/18 19:46
哈哈 謝謝各位大德回覆 已經解決。
(原來我前幾天曾經看過一篇文後測出的結果 不是錯覺 - -)
也的確是跟轉碼沒關係(這邊是陷入的第二個迷思!!)
幸好 經過這次經驗 我學得更深刻了!
謝謝各位。
我把解法PO在下面
1. 當明確知道最終字串的原始編碼(GBK) 以及最後是被哪種編碼(Big5) decoding
Encoding Big5 = Encoding.GetEncoding("Big5");
Encoding GBK = Encoding.GetEncoding("GBK");
byte[] big5_byte = Big5.GetBytes("原始字串");
string s_result = GBK.GetString(big5_byte);
2. 當不曉得最終字串是被哪種編碼decode 只知道最原始的encoding編碼
byte[] big5_byte = Encoding.Default.GetBytes(s);
string s_result = GBK.GetString(big5_byte);
一般來說 用第二種方法比較省事, 看了一篇文章 Default是照所用OS的編碼語系
當然 兩種方法僅適用經過一層的編、解碼 如果中間還經過許多步驟的邊解碼...
可能必須再靠人工一一測試了。
※ 編輯: pkmu8426 (114.46.222.47), 06/19/2014 00:06:48