微信小程序:DES3加密接口解决方案

来源:互联网 发布:手机没有usb共享网络 编辑:程序博客网 时间:2024/06/06 09:14

DES3加密:

DES3.js

var Base64 = require(‘../utils/Base64.js’)
var des3iv = ‘01234567’;
/**
* 3DES加密,CBC/PKCS5Padding
*/
function encrypt(key, input) {
var genKey = genkey(key, 0, 24);
return Base64.btoa(des(genKey.key, input, 1, 1, des3iv, 1));
}
module.exports.encrypt = encrypt;

/**
* 3DES解密,CBC/PKCS5Padding
*/
function decrypt(key, input) {
var genKey = genkey(key, 0, 24);
return des(genKey.key, Base64.atob(input), 0, 1, des3iv, 1);
}
module.exports.decrypt = decrypt;
/**
* DES 加密算法
*
* 该函数接受一个 8 字节字符串作为普通 DES 算法的密钥(也就是 64 位,但是算法只使用 56 位),或者接受一个 24 字节字符串作为 3DES
* 算法的密钥;第二个参数是要加密或解密的信息字符串;第三个布尔值参数用来说明信息是加密还是解密;接下来的可选参数 mode 如果是 0 表示 ECB
* 模式,1 表示 CBC 模式,默认是 ECB 模式;最后一个可选项是一个 8 字节的输入向量字符串(在 ECB 模式下不使用)。返回的密文是字符串。
*
* 参数:
* key: 8字节字符串作为普通 DES 算法的密钥,或 24 字节字符串作为 3DES
* message: 加密或解密的信息字符串
* encrypt: 布尔值参数用来说明信息是加密还是解密
* mode: 1:CBC模式,0:ECB模式(默认)
* iv:
* padding: 可选项, 8字节的输入向量字符串(在 ECB 模式下不使用)
*/
function des(key, message, encrypt, mode, iv, padding) {
if (encrypt) //如果是加密的话,首先转换编码
message = unescape(encodeURIComponent(message));
//declaring this locally speeds things up a bit
var spfunction1 = new Array(0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400, 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000, 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4, 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404, 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400, 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004);
var spfunction2 = new Array(-0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0, -0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020, -0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000, -0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000, -0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0, 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0, -0x7fef7fe0, 0x108000);
var spfunction3 = new Array(0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008, 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000, 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000, 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0, 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208, 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200);
var spfunction4 = new Array(0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000, 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080, 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0, 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001, 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080);
var spfunction5 = new Array(0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000, 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000, 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100, 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100, 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100, 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0, 0x40080000, 0x2080100, 0x40000100);
var spfunction6 = new Array(0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000, 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010, 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000, 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000, 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000, 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010);
var spfunction7 = new Array(0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802, 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002, 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000, 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000, 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0, 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002);
var spfunction8 = new Array(0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000, 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000, 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040, 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000);

//create the 16 or 48 subkeys we will need
var keys = des_createKeys(key);
var m = 0, i, j, temp, temp2, right1, right2, left, right, looping;
var cbcleft, cbcleft2, cbcright, cbcright2
var endloop, loopinc;
var len = message.length;
var chunk = 0;
//set up the loops for single and triple des
var iterations = keys.length == 32 ? 3 : 9; //single or triple des
if (iterations == 3) { looping = encrypt ? new Array(0, 32, 2) : new Array(30, -2, -2); }
else { looping = encrypt ? new Array(0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array(94, 62, -2, 32, 64, 2, 30, -2, -2); }

//pad the message depending on the padding parameter
if (padding == 2) message += ” “; //pad the message with spaces
else if (padding == 1) {
if (encrypt) {
temp = 8 - (len % 8);
message += String.fromCharCode(temp, temp, temp, temp, temp, temp, temp, temp);
if (temp === 8) len += 8;
}
} //PKCS7 padding
else if (!padding) message += “\0\0\0\0\0\0\0\0”; //pad the message out with null bytes

//store the result here
var result = “”;
var tempresult = “”;

if (mode == 1) { //CBC mode
cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
m = 0;
}

//loop through each 64 bit chunk of the message
while (m < len) {
left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);

//for Cipher Block Chaining mode, xor the message with the previous resultif (mode == 1) { if (encrypt) { left ^= cbcleft; right ^= cbcright; } else { cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft = left; cbcright = right; } }//first each 64 but chunk of the message must be permuted according to IPtemp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16);temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2);temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);left = ((left << 1) | (left >>> 31));right = ((right << 1) | (right >>> 31));//do this either 1 or 3 times for each chunk of the messagefor (j = 0; j < iterations; j += 3) {  endloop = looping[j + 1];  loopinc = looping[j + 2];  //now go through and perform the encryption or decryption  for (i = looping[j]; i != endloop; i += loopinc) { //for efficiency    right1 = right ^ keys[i];    right2 = ((right >>> 4) | (right << 28)) ^ keys[i + 1];    //the result is attained by passing these bytes through the S selection functions    temp = left;    left = right;    right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f]      | spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f]      | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f]      | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);  }  temp = left; left = right; right = temp; //unreverse left and right} //for either 1 or 3 iterations//move then each one bit to the rightleft = ((left >>> 1) | (left << 31));right = ((right >>> 1) | (right << 31));//now perform IP-1, which is IP in the opposite directiontemp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2);temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16);temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);//for Cipher Block Chaining mode, xor the message with the previous resultif (mode == 1) { if (encrypt) { cbcleft = left; cbcright = right; } else { left ^= cbcleft2; right ^= cbcright2; } }tempresult += String.fromCharCode((left >>> 24), ((left >>> 16) & 0xff), ((left >>> 8) & 0xff), (left & 0xff), (right >>> 24), ((right >>> 16) & 0xff), ((right >>> 8) & 0xff), (right & 0xff));chunk += 8;if (chunk == 512) { result += tempresult; tempresult = ""; chunk = 0; }

} //for every 8 characters, or 64 bits in the message
//return the result as an array
result += tempresult;
result = result.replace(/\0*$/g, “”);
if (!encrypt) { //如果是解密的话,解密结束后对PKCS7 padding进行解码,并转换成utf-8编码
if (padding === 1) { //PKCS7 padding解码
var len = result.length, paddingChars = 0;
len && (paddingChars = result.charCodeAt(len - 1));
(paddingChars <= 8) && (result = result.substring(0, len - paddingChars));
}
//转换成UTF-8编码
result = decodeURIComponent(escape(result));
}
return result;
}
function des_createKeys(key) {
//declaring this locally speeds things up a bit
var pc2bytes0 = new Array(0, 0x4, 0x20000000, 0x20000004, 0x10000, 0x10004, 0x20010000, 0x20010004, 0x200, 0x204, 0x20000200, 0x20000204, 0x10200, 0x10204, 0x20010200, 0x20010204);
var pc2bytes1 = new Array(0, 0x1, 0x100000, 0x100001, 0x4000000, 0x4000001, 0x4100000, 0x4100001, 0x100, 0x101, 0x100100, 0x100101, 0x4000100, 0x4000101, 0x4100100, 0x4100101);
var pc2bytes2 = new Array(0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808, 0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808);
var pc2bytes3 = new Array(0, 0x200000, 0x8000000, 0x8200000, 0x2000, 0x202000, 0x8002000, 0x8202000, 0x20000, 0x220000, 0x8020000, 0x8220000, 0x22000, 0x222000, 0x8022000, 0x8222000);
var pc2bytes4 = new Array(0, 0x40000, 0x10, 0x40010, 0, 0x40000, 0x10, 0x40010, 0x1000, 0x41000, 0x1010, 0x41010, 0x1000, 0x41000, 0x1010, 0x41010);
var pc2bytes5 = new Array(0, 0x400, 0x20, 0x420, 0, 0x400, 0x20, 0x420, 0x2000000, 0x2000400, 0x2000020, 0x2000420, 0x2000000, 0x2000400, 0x2000020, 0x2000420);
var pc2bytes6 = new Array(0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002, 0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002);
var pc2bytes7 = new Array(0, 0x10000, 0x800, 0x10800, 0x20000000, 0x20010000, 0x20000800, 0x20010800, 0x20000, 0x30000, 0x20800, 0x30800, 0x20020000, 0x20030000, 0x20020800, 0x20030800);
var pc2bytes8 = new Array(0, 0x40000, 0, 0x40000, 0x2, 0x40002, 0x2, 0x40002, 0x2000000, 0x2040000, 0x2000000, 0x2040000, 0x2000002, 0x2040002, 0x2000002, 0x2040002);
var pc2bytes9 = new Array(0, 0x10000000, 0x8, 0x10000008, 0, 0x10000000, 0x8, 0x10000008, 0x400, 0x10000400, 0x408, 0x10000408, 0x400, 0x10000400, 0x408, 0x10000408);
var pc2bytes10 = new Array(0, 0x20, 0, 0x20, 0x100000, 0x100020, 0x100000, 0x100020, 0x2000, 0x2020, 0x2000, 0x2020, 0x102000, 0x102020, 0x102000, 0x102020);
var pc2bytes11 = new Array(0, 0x1000000, 0x200, 0x1000200, 0x200000, 0x1200000, 0x200200, 0x1200200, 0x4000000, 0x5000000, 0x4000200, 0x5000200, 0x4200000, 0x5200000, 0x4200200, 0x5200200);
var pc2bytes12 = new Array(0, 0x1000, 0x8000000, 0x8001000, 0x80000, 0x81000, 0x8080000, 0x8081000, 0x10, 0x1010, 0x8000010, 0x8001010, 0x80010, 0x81010, 0x8080010, 0x8081010);
var pc2bytes13 = new Array(0, 0x4, 0x100, 0x104, 0, 0x4, 0x100, 0x104, 0x1, 0x5, 0x101, 0x105, 0x1, 0x5, 0x101, 0x105);

//how many iterations (1 for des, 3 for triple des)
var iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
//stores the return keys
var keys = new Array(32 * iterations);
//now define the left shifts which need to be done
var shifts = new Array(0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
//other variables
var lefttemp, righttemp, m = 0, n = 0, temp;
for (var j = 0; j < iterations; j++) { //either 1 or 3 iterations
var left = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
var right = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);

temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16);temp = ((left >>> 2) ^ right) & 0x33333333; right ^= temp; left ^= (temp << 2);temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16);temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);//the right side needs to be shifted and to get the last four bits of the left sidetemp = (left << 8) | ((right >>> 20) & 0x000000f0);//left needs to be put upside downleft = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0);right = temp;//now go through and perform these shifts on the left and right keysfor (var i = 0; i < shifts.length; i++) {  //shift the keys either one or two bits to the left  if (shifts[i]) { left = (left << 2) | (left >>> 26); right = (right << 2) | (right >>> 26); }  else { left = (left << 1) | (left >>> 27); right = (right << 1) | (right >>> 27); }  left &= -0xf; right &= -0xf;  //now apply PC-2, in such a way that E is easier when encrypting or decrypting  //this conversion will look like PC-2 except only the last 6 bits of each byte are used  //rather than 48 consecutive bits and the order of lines will be according to  //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7  lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf]    | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf]    | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf]    | pc2bytes6[(left >>> 4) & 0xf];  righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf]    | pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf]    | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf]    | pc2bytes13[(right >>> 4) & 0xf];  temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff;  keys[n++] = lefttemp ^ temp; keys[n++] = righttemp ^ (temp << 16);}

} //for each iterations
//return the keys we’ve created
return keys;
}
function genkey(key, start, end) {
//8 byte / 64 bit Key (DES) or 192 bit Key
return { key: pad(key.slice(start, end)), vector: 1 };
}
function pad(key) {
for (var i = key.length; i < 24; i++) {
key += “0”;
}
return key;
}

由于小程序不能使用 atob 和btoa BASE64加解密,这里使用了Base64.js替代了加解密:
Base64.js

var base64hash = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/’;

// btoa method
function btoa(s) {
if (/([^\u0000-\u00ff])/.test(s)) {
throw new Error(‘INVALID_CHARACTER_ERR’);
}
var i = 0,
prev,
ascii,
mod,
result = [];

while (i < s.length) {
ascii = s.charCodeAt(i);
mod = i % 3;

switch (mod) {  // 第一个6位只需要让8位二进制右移两位  case 0:    result.push(base64hash.charAt(ascii >> 2));    break;  //第二个6位 = 第一个8位的后两位 + 第二个8位的前4位  case 1:    result.push(base64hash.charAt((prev & 3) << 4 | (ascii >> 4)));    break;  //第三个6位 = 第二个8位的后4位 + 第三个8位的前2位  //第4个6位 = 第三个8位的后6位  case 2:    result.push(base64hash.charAt((prev & 0x0f) << 2 | (ascii >> 6)));    result.push(base64hash.charAt(ascii & 0x3f));    break;}prev = ascii;i++;

}

// 循环结束后看mod, 为0 证明需补3个6位,第一个为最后一个8位的最后两位后面补4个0。另外两个6位对应的是异常的“=”;
// mod为1,证明还需补两个6位,一个是最后一个8位的后4位补两个0,另一个对应异常的“=”
if (mod == 0) {
result.push(base64hash.charAt((prev & 3) << 4));
result.push(‘==’);
} else if (mod == 1) {
result.push(base64hash.charAt((prev & 0x0f) << 2));
result.push(‘=’);
}

return result.join(”);
}
module.exports.btoa = btoa;

// atob method
// 逆转encode的思路即可
function atob(s) {
s = s.replace(/\s|=/g, “”);
var cur,
prev,
mod,
i = 0,
result = [];
while (i < s.length) {
cur = base64hash.indexOf(s.charAt(i));
mod = i % 4;
switch (mod) {
case 0:
break;
case 1:
result.push(String.fromCharCode(prev << 2 | cur >> 4));
break;
case 2:
result.push(String.fromCharCode((prev & 0x0f) << 4 | cur >> 2));
break;
case 3:
result.push(String.fromCharCode((prev & 3) << 6 | cur));
break;
}
prev = cur;
i++;
}
return result.join(”);
}
module.exports.atob = atob;

原创粉丝点击