日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

js处理16进制hex转str出现的中文乱码问题

發(fā)布時間:2025/3/11 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js处理16进制hex转str出现的中文乱码问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

昨天從FB下載了一份包含所有對話紀(jì)錄的JSON檔,但裡面的中文字編碼有問題,通通變成下面這個樣子

"\u00e7\u0094\u009f\u00e6\u0097\u00a5"

本來想說這種事情應(yīng)該很簡單,就把他每個字元當(dāng)成char轉(zhuǎn)存不就得了,結(jié)果轉(zhuǎn)出來的東西從網(wǎng)頁上看還是一團(tuán)亂碼…

錯誤的嘗試

既然轉(zhuǎn)換之後仍然是亂碼,那至少代表這個編碼不是utf-8,那會不會是big5或其他現(xiàn)在比較少看到的編碼呢?所以我試著切換 html 檔的 charset,但仍然得到錯誤的結(jié)果

??¥????¨? //這到底是什麼鬼東西

整理思路

後來注意到一件小事情是,他所有的16進(jìn)位資料都是\u00開頭,或許意味著只有後兩位有意義?於是我把字頭全部取代後得到下面的結(jié)果

E7 94 9F E6 97 A5

這東西看起來很像是在使用記憶體修改器會看到的東西,於是我稍微有思緒了:他實際上應(yīng)該是byte[]。也循線找到了網(wǎng)站測試證明了我的想法是正確的

Hex decoder: Online hexadecimal to text converter

byte array to string

搞懂他到底是什麼編碼格式之後,就是要開始寫轉(zhuǎn)檔程式了(總不能一行一行貼上去面的網(wǎng)站翻譯吧)在 stackoverflow 上有這麼一篇提問:How to convert UTF8 string to byte array??下方的解答有人分享了轉(zhuǎn)換的規(guī)則:

  • 多位元組的情形下,第一個位元組前面1的數(shù)量即代表該字元所需要的位元組數(shù)量。扣除這個資訊所占用的位元後剩下的位元即為資料區(qū)塊
  • 後面接著的延續(xù)位元組,其格式固定為10字頭,後面的六個位元為資料區(qū)塊
  • 將所有的資料區(qū)塊全部拼起來即為utf-8碼

以我上面分享的第一個字為例子
前三碼E7 94 9F轉(zhuǎn)成二進(jìn)制的資料呈現(xiàn)以下的樣子

11100111 10010100 10011111
  • 第一組前面有3個1,代表這個字要用到三個位元組
  • 扣除記錄這個資訊的區(qū)塊後,剩下的00111即為第一塊資料區(qū)
  • 第二組為延續(xù)位元組,其前兩碼固定為10,後面的010100即為資料區(qū)
  • 第三組為延續(xù)位元組,其前兩碼固定為10,後面的011111即為資料區(qū)
  • 三組資料全部拼起來00111010100011111就是這個字的 utf-8 碼
  • 把這個二進(jìn)制資料轉(zhuǎn)回 int 後再轉(zhuǎn)成 char 就會看到正確的中文字了 String.fromCharCode(parseInt('00111010100011111',2)) //'生'
  • 寫成程式

    最後就是把上面的邏輯寫成程式碼了

    function hex2a(hexx) {var hex = hexx.toString();//force conversionvar str = '';for (var i = 0; (i < hex.length && hex.substr(i, 2) !== '00'); i += 2)str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));return str; }function decode(text) {if (!text)return "";//string to byte[]let byteArr = [];for (let i = 0; i < text.length; i++) {byteArr.push(text.charCodeAt(i));}let str = "";for (let i = 0; i < byteArr.length;) {let binary = byteArr[i].toString(2);let head = binary.match(/^1+?(?=0)/);if (head && binary.length == 8) {//該字元需要幾個位元組let bytesLength = head[0].length;//第一個位元組的實際資料區(qū) let body = binary.slice(bytesLength);for (let j = 1; j < bytesLength; j++) {//組合資料body += byteArr[i + j].toString(2).slice(2);}str += String.fromCharCode(parseInt(body, 2));i += bytesLength;} else {str += String.fromCharCode(byteArr[i]);i++;}}return str; }aa=decode("\u00e7\u0094\u009f\u00e6\u0097\u00a5"); // returns '2460'console.log(aa)

    view rawbyte-array-to-string.js?hosted with ? by?GitHub

    ?

    後記

    • 好久沒有碰到需要直接操作位元的問題,大學(xué)修的計概都還給教授了Orz
    • 組資料的地方如果可以直接用<<跟>>進(jìn)行位元計算性能應(yīng)該會比字串處理提升很多,改天再來修改程式碼吧。
    • 實測發(fā)現(xiàn)emoji轉(zhuǎn)不出來🤔🤔🤔

    總結(jié)

    以上是生活随笔為你收集整理的js处理16进制hex转str出现的中文乱码问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。