GBK與UTF 8編碼錯誤轉換後,無法再正確恢復

2022-03-31 20:50:35 字數 1188 閱讀 3868

utf-8格式編碼的位元組流,按gbk字符集轉換為字串,會出現亂碼,這很正常。但將其重新轉為位元組流,再用utf-8字符集轉為字串,還是亂碼。這就讓我產生了疑惑,雖然使用錯誤的字符集必然導致亂碼,但位元組的資訊並沒有改變,因此再轉為位元組流,用正確的字符集解碼,應該得到正常的字串。但事實是,被錯誤字符集轉換過的字串,無法恢復到原來的字符集。

造成該問題的根源是位元組發生了變化。gbk或utf-8遇到無法解析的字元時,會使用特殊的字元代替,因此造成原有位元組資訊的丟失,無法恢復。

utf-8 → gbk

對於一串utf-8編碼的位元組流,使用gbk進行解碼。連續兩個大於127的位元組被認為是乙個gbk編碼的字元;若唯讀到乙個大於127的位元組,便發生錯誤,無法解析。此時,用字元'?'代替錯誤位元組,ascii碼是63。

「樊」字為例,utf-8編碼使用三個位元組表示該字元,位元組碼為[11100110, 10101000, 10001010]([e6, a8, 8a])。使用gbk解碼時,讀到第乙個位元組大於127,則取兩個位元組解析為乙個gbk字元。前兩個位元組e6 8a被解析為gbk字元——妯。 第三個位元組無法解析,所以賦值為?,最後的結果是妯?

可以看出,最後乙個位元組的資訊丟失了,由8a變成3f,即使把結果再轉換為位元組流,也無法用utf-8字符集正確解析了。

gbk → utf-8

對於一串gbk編碼的位元組流,使用utf-8解碼。utf-8對於位元組的格式有嚴格要求,當解析某個字元失敗時,使用'�'(utf-8編碼為ef bf bd)代替。

繼續以「樊」字為例,其gbk位元組碼為[10110111, 10101110]([b7, ae])。使用utf-8解碼時,根據規則,要求10開頭的位元組之前,必須有位元組標識乙個字元的長度,所以兩個位元組都無法解析。最後的字串是��。

可以看出,所有的位元組資訊都丟失了,因此無法再使用gbk解析該字串。

注意,utf-8用�替換,是以字元為單位的。例如[11100110, 10101000, 01000001]使用utf-8解碼,得到的結果是�a,而不是��a。根據第乙個位元組的格式,utf-8期望將三個位元組轉換為乙個字元。但最後乙個位元組不符合要求,所以前兩個位元組被乙個�代替。而不是每個位元組都被�代替。

gbk 轉換 utf 8問題

問題一 檔案已經另存為了utf 8碼,但關閉後重新開啟就自動變成了ansi編碼 答 原因是該檔案中沒有包含任何中文字元,如果該檔案有包含中文字元,將檔案另存為utf 8編碼後,中文字元會以3個位元組的寬度來儲存 要看16進製制 這樣,在第二次開啟檔案時,編輯器會自動將檔案識別為utf 8編碼。請仔細...

ANSI與UTF 8編碼轉換

將ansi編碼裝換為utf 8在windows mfc環境下測試下面的 static int ansi2utf8 in const char csrc,out char cdest 以下 將utf 8 轉換為gb2312 intutf8togb2312 const char sourcebuf,si...

UTF 8與GBK字元之間的轉換

1.utf 8轉換為unicode編碼 utf 8編碼不能直接轉換為gbk漢字編碼,中間需要先轉換為unicode編碼,在由unicode編碼轉換為gbk漢字編碼 2.unicode編碼轉換為gbk漢字編碼 unicode漢字編碼與gbk漢字編碼的對照關係為,兩個unicode編碼對應乙個漢字,並且...