java字串轉碼問題 從utf 8轉到gbk再轉回utf 8為什麼會出現部分亂碼呢?

時間 2021-05-29 22:42:15

1樓:飲冰

木女孩說的沒錯,確實是漏下了。

補充一下。

發現只要是偶數個字就能轉過去,奇數個字的話會因為GBK沒法找到最後2個位元組,所以轉換過去末尾會出現亂碼。

2樓:彭祖雲

指定資料流的編碼和長度,完美!

我回答的是http中亂碼,搜尋問題發現這個問題就答個其他類似的。

3樓:木女孩

假設啊(具體不是醬紫的啊,內部還比較複雜),每個字用UTF-8編碼需要使用3個位元組,每個字用GBK編碼需要2個位元組。

好,我們現在開始轉換:

先看這個吧,a.getBytes("utf-8"),"gbk"

把這三個字用UTF-8翻譯成位元組陣列,嗯,翻譯後佔9個位元組

把上面的位元組陣列用GBK翻譯成字串,每次取出兩個位元組翻譯成乙個字,於是前8個位元組似乎沒有什麼太大問題(其實有問題,下面說),翻譯成了4個字。然後只剩乙個位元組了,這要怎麼搞,人家自己會給你加乙個位元組,湊成兩個,然後再翻譯。也就是說一共有5個字對吧,你看看你的輸出:

鎴戝緢濂

再看下面這個,b.getBytes("gbk"),"utf-8"

把「鎴戝緢濂」用GBK翻譯成位元組陣列,這個沒什麼問題吧,就翻譯成了上面那10個位元組(最後乙個位元組是他自己加的)

把這10個位元組用UTF-8翻譯成字串,先取出三個,翻譯成了我,再取出三個,翻譯成了很,再取出三個,似乎沒有翻譯成好啊,問題在哪?上面說的「其實有問題就在這裡」,你那隨便取的兩個位元組,我這GBK就一定有對應的字啊,沒有對應的怎麼辦,找乙個比較接近的代替,也就是說原來的位元組陣列被改變了。所以這裡在翻譯回去就出了問題。

最後還剩乙個位元組啊(就是上面他自己加的那個),這裡要三個位元組才能翻譯啊,那就再加兩個唄,就湊成三個了,於是這個可想而知要翻譯成什麼亂七八糟的玩意兒。

所以就上面的分析可以引出的問題有倆:

翻譯成字串時,取出若干個位元組,發現我這個碼表裡面沒有與之對應的字,使用其他接近的代替

前面每次取出幾個來翻譯都很開心,最後發現不夠了,要自己加幾個位元組才能翻譯

一般使用Tomcat的時候,他預設使用ISO-8859-1(這是Servlet規範要求的)給你解析,明顯中文就要亂碼,出現這個亂碼了,可以怎麼搞啊:

String a = "我很好";

String b=new String(a.getBytes("utf-8"),"ISO-8859-1");

System.out.println(b);

String c=new String(b.getBytes("ISO-8859-1"),"utf-8");

System.out.println(c);

很多老師或者老濕機會給你這麼說吧,這個一點問題都沒有。ISO-8859-1一次只要乙個位元組,而且使用了單位元組內的所有空間,換句話說隨便拿乙個位元組,我都能給你翻譯,不會出現問題1所說的現象;他每次只要乙個位元組,自然就不會有問題2所說的現象,所以這是ok的。

菜鳥強答,有什麼不對的要指出來啊。

如何從幾十億字串(每個字串不超過200位元組)中,查詢出,包含某個子串所有字串

建議使用 KMP 演算法,如果是找出出現的位置,時間複雜度為 O 幾十億字串 的總長 某個子串 的長度 但題主問的是 包含某個子串所有字串 那這樣的字串就可以有很多個,而且你得輸出字串而不只是位置,那麼複雜度會大很多。最壞情況下,幾十億字串 中每乙個都是 200 個 a,某個子串 是乙個 a,那麼你...

Mathematica字串匹配的問題?

燕南 In 1 str Round 1 Aug 16 Arsenal 2 1 Crystal PLeicester 2 2 EvertonManchester U 1 2 SwanseaQPR 0 1 Hull Stoke 0 1 Aston VillaWest Bromwich 2 2 Sunde...

字串搜尋問題,如何找出字串 S 求最長的形式為 x yy 的字首

王天賜 應該不需要擴充套件kmp。直接執行kmp演算法,求出fail函式。對於任意乙個字首,可以根據它的長度和它結尾位置所對應的fail值求出這個字首的最小週期。然後檢查一下該字首的最小週期能不能整除字首長度的一半就好了 實際上是檢查長度的一半是不是乙個週期 z algorithm 和擴充套件kmp...