js base32编码解码

参考博客:https://www.jianshu.com/p/81e5a2e3036f

他这个不完整,我补全了一下

有错误待纠正,可参考c++的代码,主要是不足位数时的补0和对应的解码。

base3264.js

const UTF8EncodeDecode = {
    _utf8_encode: function (e) {
        // 把全局的rn替换成n
        e = e.replace(/rn/g, "n");
        var t = "";
        for (var n = 0; n < e.length; n++) {
            // charCodeAt() 方法可返回指定位置的字符的 Unicode 编码,返回值是 0 - 65535 之间的整数,表示给定索引处的 UTF-16 代码单元。
            var r = e.charCodeAt(n);
            if (r < 128) {
                t += String.fromCharCode(r)
            } else if (r > 127 && r < 2048) {
                t += String.fromCharCode(r >> 6 | 192);
                t += String.fromCharCode(r & 63 | 128)
            } else {
                t += String.fromCharCode(r >> 12 | 224);
                t += String.fromCharCode(r >> 6 & 63 | 128);
                t += String.fromCharCode(r & 63 | 128)
            }
        }
        return t;
    },
    _utf8_decode: function (e) {
        var t = "";
        var n = 0;
        var r = c1 = c2 = 0;
        while (n < e.length) {
            r = e.charCodeAt(n);
            if (r < 128) {
                t += String.fromCharCode(r);
                n++
            } else if (r > 191 && r < 224) {
                c2 = e.charCodeAt(n + 1);
                t += String.fromCharCode((r & 31) << 6 | c2 & 63);
                n += 2
            } else {
                c2 = e.charCodeAt(n + 1);
                c3 = e.charCodeAt(n + 2);
                t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
                n += 3
            }
        }
        return t;
    }
}

const Base32 = {
    _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=",
    encode: function (str) {
        var ans = "";
        let char=[0,0,0,0,0], code=[0,0,0,0,0,0,0,0];
        let index = 0;
        // 先将字符转成UTF8编码的字符
        str = UTF8EncodeDecode._utf8_encode(str);
        // Base32 是每5个bit编码成一个字符,一个char8个bit,那么每次需要拿5个char共40(5*8=40)个bit,然后拆分成8个5bit
        // |xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|
        // |xxxxx|xxxxx|xxxxx|xxxxx|xxxxx|xxxxx|xxxxx|xxxxx|
        while (index < str.length)
        {
            for(let i=0;i<5;i++)char[i]=str.charCodeAt(index++);
            code[0]=char[0]>>3;
            code[1]=(char[0]&7)<<2|(char[1]>>6);
            code[2]=(char[1]>>1)&31;
            code[3]=((char[1]&1)<<4)|(char[2]>>4);
            code[4]=((char[2]&15)<<1)|(char[3]>>7);
            code[5]=(char[3]>>2)&31;
            code[6]=((char[3]&3)<<3)|(char[4]>>5);
            code[7]=char[4]&31;

            for(let i=1;i<5;i++)
                if(isNaN(char[i]))
                    for(let j=i*8/5+1;j<8;j++)code[j]=32;
            for(let i=0;i<8;i++)ans = ans+this._keyStr.charAt(code[i]);
        }
        return ans;
    },
    decode: function (str) {
        let ans = "";
        let char=[0,0,0,0,0], code=[0,0,0,0,0,0,0,0];
        let index = 0;
        // 去除掉不符合要求的字符
        str = str.replace(/[^A-Z2-7=]/g, "");
        while (index < str.length) {
            for(let i=0;i<8;i++)code[i]=this._keyStr.indexOf(str.charAt(index++));

            char[0] = (code[0]<<3)|(code[1]>>2);
            char[1] = ((code[1]&3)<<6)|(code[2]<<1)|(code[3]>>4);
            char[2] = ((code[3]&15)<<4)|(code[4]>>1);
            char[3] = ((code[4]&1)<<7)|(code[5]<<2)|(code[6]>>3);
            char[4] = ((code[6]&7)<<5)|code[7];

            ans = ans + String.fromCharCode(char[0]);
            if (char[2] != 32)ans = ans + String.fromCharCode(char[1]);
            if (char[4] != 32)ans = ans + String.fromCharCode(char[2]);
            if (char[5] != 32)ans = ans + String.fromCharCode(char[3]);
            if (char[7] != 32)ans = ans + String.fromCharCode(char[4]);
        }
        ans = UTF8EncodeDecode._utf8_decode(ans);
        return ans;
    }
}

const Base64 = {
    _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
    encode: function (str) {
        var ans = "";
        let char1, char2, char3, code1, code2, code3, code4;
        let index = 0;
        // 先将字符转成UTF8编码的字符
        str = UTF8EncodeDecode._utf8_encode(str);
        // Base64 是每6个bit编码成一个字符,一个char8个bit,那么每次需要拿3个char共24(3*8=24)个bit,然后拆分成4个6bit
        // |xxxxxxxx|xxxxxxxx|xxxxxxxx|
        // |xxxxxx|xxxxxx|xxxxxx|xxxxxx|
        while (index < str.length)
        {
            char1 = str.charCodeAt(index++);
            char2 = str.charCodeAt(index++);
            char3 = str.charCodeAt(index++);

            code1 = char1 >> 2;
            code2 = (char1 & 3) << 4 | char2 >> 4;
            code3 = (char2 & 15) << 2 | char3 >> 6;
            code4 = char3 & 63;
            if (isNaN(char2)) {
                code3 = code4 = 64;
            } else if (isNaN(char3)) {
                code4 = 64;
            }
            ans = ans + this._keyStr.charAt(code1) + this._keyStr.charAt(code2) + this._keyStr.charAt(code3) + this._keyStr.charAt(code4)
        }
        return ans;
    },
    decode: function (str) {
        let ans = "";
        let code1, code2, code3, code4, char1, char2, char3;
        let index = 0;
        // 去除掉不符合要求的字符
        str = str.replace(/[^A-Za-z0-9+/=]/g, "");
        while (index < str.length) {
            code1 = this._keyStr.indexOf(str.charAt(index++));
            code2 = this._keyStr.indexOf(str.charAt(index++));
            code3 = this._keyStr.indexOf(str.charAt(index++));
            code4 = this._keyStr.indexOf(str.charAt(index++));

            char1 = (code1 << 2) | (code2 >> 4);
            char2 = ((code2 & 15) << 4) | (code3 >> 2);
            char3 = ((code3 & 3) << 6) | code4;

            ans = ans + String.fromCharCode(char1);
            if (code3 != 64)ans = ans + String.fromCharCode(char2);
            if (code4 != 64)ans = ans + String.fromCharCode(char3);
        }
        ans = UTF8EncodeDecode._utf8_decode(ans);
        return ans;
    }
}

function StringToBase32(srcString) {
    let ans='';
    if (srcString) ans=Base32.encode(srcString);
    return ans;
}

function Base32ToString(srcString)
{
    let ans='';
    if (srcString) ans=Base32.decode(srcString);
    return ans;
}

function StringToBase64(srcString) {
    let ans='';
    if (srcString) ans=Base64.encode(srcString);
    return ans;
}

function Base64ToString(srcString) {
    let ans='';
    if (srcString) ans=Base64.decode(srcString);
    return ans;
}

测试样例:

main.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
</body>


<script type="text/javascript" src="./base3264.js"></script>


<script>
let raw_str="hello world!a *Du9 0zhzc咋时间都i啊";
console.log(raw_str);
let base32_encode_str = StringToBase32(raw_str);
console.log(base32_encode_str);
let base32_decode_str = Base32ToString(base32_encode_str);
console.log(base32_decode_str);

let base64_encode_str = StringToBase64(raw_str);
console.log(base64_encode_str);
let base64_decode_str = Base64ToString(base64_encode_str);
console.log(base64_decode_str);
</script>

</html>
文章目录