問題
最近使用protobuf(google出品的一種序列化協(xié)議)存儲中文時,看到一種類似\346\200\241\346\200\241\346\200的編碼,試用各種常用的編碼格式用編碼轉(zhuǎn)換工具都不可以,在java,python中卻可以在不明確指定編碼方式的情況下識別成功,現(xiàn)在需要在web頁解碼方便直接查看,js默認的解編碼函數(shù)搞不定。所以查查看
八進制編碼
其實他還是utf8編碼,不過通常的utf8編碼使用16進制表示,這種編碼不常見的使用了8進制表示。其實將這里的8進制轉(zhuǎn)為16進制,和utf8的編碼是完全一致的,也就是說在內(nèi)存中的字節(jié)是一致的,所以可以被java,python直接識別,但是按8進制方式顯示,就顯得很特別了。
# 在python中可以直接用decode("utf-8")解:
>>> print("\344\275\240\345\245\275".decode("utf-8"))
你好
utf8的多種形式
"你好"的各個平臺編碼,他們之間的區(qū)別就是編碼的二進制的不同的可讀方式,八進制確實用的少。
| 平臺 | 舉例 | 備注 |
|---|---|---|
| 在線轉(zhuǎn)碼平臺 | 你好 |
就是把unicode的 \u 前綴轉(zhuǎn)為了 &#x |
| python | \xe4\xb8\xad\xe6\x96\x87 |
就是utf8 每個字節(jié)16進制的前面加上 \x |
| url | %E4%BD%A0%E5%A5%BD |
utf8 每個字節(jié)16進制的前面加上 % |
| protoBuf | \344\275\240\345\245\275 |
utf8 每個字節(jié)8進制的前面加上 \ |
js實現(xiàn) 八進制utf8的解碼
沒有成品,就自己造。思路就是正則匹配字符串,三位三位拿,轉(zhuǎn)為16進制,加%轉(zhuǎn)為url的編碼方式,然后使用js的解碼函數(shù)decodeURIComponent() 解碼最終得到中文。
function decodeOctUtf8(octStr){
decoded = octStr.replace(/(\\\d\d\d){3,}/g, function(word){
tokens = word.split("\\")
encoded = ''
tokens.forEach(function(token, idx){
if(token.length > 0){ // 去掉split函數(shù)產(chǎn)生的空字符串
encoded += "%" + parseInt(token, 8).toString(16)
}
})
return decodeURIComponent(encoded);
});
return decoded
}
總結(jié)
至此問題解決了。代碼離不開編碼的處理,常用有很多種編碼方式,編碼的核心作用就是把文字映射到二進制,方便機器理解計算。在讀寫文件,web傳輸時常常需要指定編碼方式,但我們也不需要關注編碼的"長相",因此碰見一個不常見的“長相”,還以為是不常用或者經(jīng)過了壓縮的編碼。