Protobuf中少見(jiàn)的八進(jìn)制編碼.md

問(wèn)題

最近使用protobuf(google出品的一種序列化協(xié)議)存儲(chǔ)中文時(shí),看到一種類似\346\200\241\346\200\241\346\200的編碼,試用各種常用的編碼格式用編碼轉(zhuǎn)換工具都不可以,在java,python中卻可以在不明確指定編碼方式的情況下識(shí)別成功,現(xiàn)在需要在web頁(yè)解碼方便直接查看,js默認(rèn)的解編碼函數(shù)搞不定。所以查查看

八進(jìn)制編碼

其實(shí)他還是utf8編碼,不過(guò)通常的utf8編碼使用16進(jìn)制表示,這種編碼不常見(jiàn)的使用了8進(jìn)制表示。其實(shí)將這里的8進(jìn)制轉(zhuǎn)為16進(jìn)制,和utf8的編碼是完全一致的,也就是說(shuō)在內(nèi)存中的字節(jié)是一致的,所以可以被java,python直接識(shí)別,但是按8進(jìn)制方式顯示,就顯得很特別了。

# 在python中可以直接用decode("utf-8")解:
>>> print("\344\275\240\345\245\275".decode("utf-8"))
你好

utf8的多種形式

"你好"的各個(gè)平臺(tái)編碼,他們之間的區(qū)別就是編碼的二進(jìn)制的不同的可讀方式,八進(jìn)制確實(shí)用的少。

平臺(tái) 舉例 備注
在線轉(zhuǎn)碼平臺(tái) 你好 就是把unicode的 \u 前綴轉(zhuǎn)為了 &#x
python \xe4\xb8\xad\xe6\x96\x87 就是utf8 每個(gè)字節(jié)16進(jìn)制的前面加上 \x
url %E4%BD%A0%E5%A5%BD utf8 每個(gè)字節(jié)16進(jìn)制的前面加上 %
protoBuf \344\275\240\345\245\275 utf8 每個(gè)字節(jié)8進(jìn)制的前面加上 \

js實(shí)現(xiàn) 八進(jìn)制utf8的解碼

沒(méi)有成品,就自己造。思路就是正則匹配字符串,三位三位拿,轉(zhuǎn)為16進(jìn)制,加%轉(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é)

至此問(wèn)題解決了。代碼離不開(kāi)編碼的處理,常用有很多種編碼方式,編碼的核心作用就是把文字映射到二進(jìn)制,方便機(jī)器理解計(jì)算。在讀寫(xiě)文件,web傳輸時(shí)常常需要指定編碼方式,但我們也不需要關(guān)注編碼的"長(zhǎng)相",因此碰見(jiàn)一個(gè)不常見(jiàn)的“長(zhǎng)相”,還以為是不常用或者經(jīng)過(guò)了壓縮的編碼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容