1. 程式人生 > 其它 >javascript實現base64格式轉碼與解碼

javascript實現base64格式轉碼與解碼

  最近碰到一個需求,後端返回base64格式的資料,前端需要進行base64格式解碼,好了,前端採用內部提供的atob函式進行解碼,開完成,交付測試,然後測試返回說中文亂碼!

  然後查了一下,我後端程式碼採用utf8編碼,這沒問題,問題出在前端使用的atob函式,它居然採用的是Latin1(ISO-8859-1)編碼!還不能修改編碼方式,而且它還只在web端開發有這個atob函式!也不知道寫這個atob函式的作者出於什麼目的,Latin1(ISO-8859-1)編碼用的很廣麼?豎中指!!!!

  沒辦法,問題要解決,我們本可以找一下第三方的包,但想想,還是覺的自己實現一個轉碼的函式,留著備用,這裡分享出來:

    let base64util = function () {
        let _keys = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

        //base64格式加密
        function encode(input) {
            if (typeof input != "string") {
                input = JSON.stringify(input)
            }

            //utf8轉碼
let buffer = []; for (var n = 0; n < input.length; n++) { var c = input.charCodeAt(n); if (c < 128) { //一個位元組 buffer.push(c); } else if (c < 2048) { //兩個位元組 buffer.push((c >> 6) | 192, (c & 63) | 128); }
else if (c < 65536) { //三個位元組 buffer.push((c >> 12) | 224, ((c >> 6) & 63) | 128, (c & 63) | 128); } else if (c < 2097152) { //四個位元組 buffer.push((c >> 18) | 240, ((c >> 12) & 63) | 128, ((c >> 6) & 63) | 128, (c & 63) | 128); } else if (c < 67108863) { //五個位元組 buffer.push((c >> 24) | 248, ((c >> 18) & 63) | 128, ((c >> 12) & 63) | 128, ((c >> 6) & 63) | 128, (c & 63) | 128); } else { //六個位元組 buffer.push((c >> 30) | 252, ((c >> 24) & 63) | 128, ((c >> 18) & 63) | 128, ((c >> 12) & 63) | 128, ((c >> 6) & 63) | 128, (c & 63) | 128); } } //轉碼 let i = 0, padding = buffer.length % 3; padding && buffer.push(...new Array(padding = 3 - padding).fill(0));//先用0填補 let result = [] while (i < buffer.length) { let [c1, c2, c3] = [buffer[i++], buffer[i++], buffer[i++]]; result.push(c1 >> 2, ((c1 & 0b11) << 4) | (c2 >> 4), ((c2 & 0b1111) << 2) | (c3 >> 6), c3 & 63); } padding && (result.splice(result.length - padding), result.push(...new Array(padding).fill(64)));//把0填補換成= return result.map(v => _keys.charAt(v)).join(""); } //base64格式解碼 function decode(input) { if (typeof input != "string") { throw "invalid argument" } //解碼 let buffer = input.split(""), i = 0, padding; let r = [] while (i < buffer.length) { let array = buffer.slice(i, i += 4).map(v => _keys.indexOf(v)) if (array.length != 4 || array.some(v => v < 0)) throw "invalid input" padding = array.filter(v => v == 64).length;//獲取填補的=號數量 padding && (array.splice(r.length - padding), array.push(...new Array(padding).fill(0)));//把=填補換成0 let [e1, e2, e3, e4] = array r.push((e1 << 2) | (e2 >> 4), ((e2 & 15) << 4) | (e3 >> 2), ((e3 & 3) << 6) | e4); } padding && r.splice(r.length - padding)//去掉填補 //utf8轉碼 i = 0; buffer = []; while (i < r.length) { let c = r[i++] if (c < 128) //一個位元組 buffer.push(c); else if (c < 224) //兩個位元組 buffer.push(((c & 0b11111) << 6) | (r[i++] & 63)); else if (c < 240) //三個位元組 buffer.push(((c & 0b1111) << 12) | ((r[i++] & 63) << 6) | (r[i++] & 63)); else if (c < 248) //四個位元組 buffer.push(((c & 0b1111) << 18) | ((r[i++] & 63) << 12) | ((r[i++] & 63) << 6) | (r[i++] & 63)); else if (c < 252) //五個位元組 buffer.push(((c & 0b1111) << 24) | ((r[i++] & 63) << 18) | ((r[i++] & 63) << 12) | ((r[i++] & 63) << 6) | (r[i++] & 63)); else //六個位元組 buffer.push(((c & 0b1111) << 30) | ((r[i++] & 63) << 25) | ((r[i++] & 63) << 18) | ((r[i++] & 63) << 12) | ((r[i++] & 63) << 6) | (r[i++] & 63)); } return buffer.map(v => String.fromCharCode(v)).join(""); } return { encode, decode }; atob }()

  使用:  

    //轉碼
    base64util.encode("say:上山打老虎")
    //解碼
    base64util.decode("c2F5OuS4iuWxseaJk+iAgeiZjg==")

  結果:

  

一個專注於.NetCore的技術小白