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>