JS加解密(3des)亦可用于小程序

/**

  • 3DES 加密算法
  • 該函數(shù)接受一個(gè) 8 字節(jié)字符串作為普通 DES 算法的密鑰(也就是 64 位,但是算法只使用 56 位),或者接受一個(gè) 24 字節(jié)字符串作為 3DES
  • 算法的密鑰;第二個(gè)參數(shù)是要加密或解密的信息字符串;第三個(gè)布爾值參數(shù)用來說明信息是加密還是解密;接下來的可選參數(shù) mode 如果是 0 表示 ECB
  • 模式,1 表示 CBC 模式,默認(rèn)是 ECB 模式;最后一個(gè)可選項(xiàng)是一個(gè) 8 字節(jié)的輸入向量字符串(在 ECB 模式下不使用)。返回的密文是字符串。
  • 參數(shù):
  • key: 8字節(jié)字符串作為普通 DES 算法的密鑰,或 24 字節(jié)字符串作為 3DES
  • message: 加密或解密的信息字符串
  • encrypt: 布爾值參數(shù)用來說明信息是加密還是解密
  • mode: 1:CBC模式,0:ECB模式(默認(rèn))
  • iv:
  • padding: 可選項(xiàng), 8字節(jié)的輸入向量字符串(在 ECB 模式下不使用)
    /
    //this takes the key, the message, and whether to encrypt or decrypt
    function des(key, message, encrypt, mode, iv, padding) {
    if (encrypt) //如果是加密的話,首先轉(zhuǎn)換編碼
    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 result
    if (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 IP
    temp = ((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 message
    for (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 right
    left = ((left >>> 1) | (left << 31));
    right = ((right >>> 1) | (right << 31));
    //now perform IP-1, which is IP in the opposite direction
    temp = ((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 result
    if (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) { //如果是解密的話,解密結(jié)束后對(duì)PKCS7 padding進(jìn)行解碼,并轉(zhuǎn)換成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));
    }
    //轉(zhuǎn)換成UTF-8編碼
    result = decodeURIComponent(escape(result));
    }
    return result;
    } //end of des
    //des_createKeys
    //this takes as input a 64 bit key (even though only 56 bits are used)
    //as an array of 2 integers, and returns 16 48 bit keys
    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 side
    temp = (left << 8) | ((right >>> 20) & 0x000000f0);
    //left needs to be put upside down
    left = (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 keys
    for (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;
    } //end of des_createKeys
    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;
}

var base64hash = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

// btoa method
//base64 編碼
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) {
        // 第一個(gè)6位只需要讓8位二進(jìn)制右移兩位
        case 0:
            result.push(base64hash.charAt(ascii >> 2));
            break;
            //第二個(gè)6位 = 第一個(gè)8位的後兩位 + 第二個(gè)8位的前4位
        case 1:
            result.push(base64hash.charAt((prev & 3) << 4 | (ascii >> 4)));
            break;
            //第三個(gè)6位 = 第二個(gè)8位的後4位 + 第三個(gè)8位的前2位
            //第4個(gè)6位 = 第三個(gè)8位的後6位
        case 2:
            result.push(base64hash.charAt((prev & 0x0f) << 2 | (ascii >> 6)));
            result.push(base64hash.charAt(ascii & 0x3f));
            break;
    }

    prev = ascii;
    i++;
}

// 循環(huán)結(jié)束後看mod, 為0 證明需補(bǔ)3個(gè)6位,第一個(gè)為最後一個(gè)8位的最後兩位後面補(bǔ)4個(gè)0。另外兩個(gè)6位對(duì)應(yīng)的是異常的“=”;
// mod為1,證明還需補(bǔ)兩個(gè)6位,一個(gè)是最後一個(gè)8位的後4位補(bǔ)兩個(gè)0,另一個(gè)對(duì)應(yīng)異常的“=”
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('');

}
//解碼 成 ASCII
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:
            //TODO
            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('');

}
var base64hash = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

// btoa method
//base64 編碼
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) {
        // 第一個(gè)6位只需要讓8位二進(jìn)制右移兩位
        case 0:
            result.push(base64hash.charAt(ascii >> 2));
            break;
            //第二個(gè)6位 = 第一個(gè)8位的後兩位 + 第二個(gè)8位的前4位
        case 1:
            result.push(base64hash.charAt((prev & 3) << 4 | (ascii >> 4)));
            break;
            //第三個(gè)6位 = 第二個(gè)8位的後4位 + 第三個(gè)8位的前2位
            //第4個(gè)6位 = 第三個(gè)8位的後6位
        case 2:
            result.push(base64hash.charAt((prev & 0x0f) << 2 | (ascii >> 6)));
            result.push(base64hash.charAt(ascii & 0x3f));
            break;
    }

    prev = ascii;
    i++;
}

// 循環(huán)結(jié)束後看mod, 為0 證明需補(bǔ)3個(gè)6位,第一個(gè)為最後一個(gè)8位的最後兩位後面補(bǔ)4個(gè)0。另外兩個(gè)6位對(duì)應(yīng)的是異常的“=”;
// mod為1,證明還需補(bǔ)兩個(gè)6位,一個(gè)是最後一個(gè)8位的後4位補(bǔ)兩個(gè)0,另一個(gè)對(duì)應(yīng)異常的“=”
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('');

}
//解碼 成 ASCII
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:
            //TODO
            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('');

}

var des3iv = 'ubspnhcw';
var key = '2rnet2sq';
var DES3 = {
//3DES加密,CBC/PKCS5Padding
encrypt: function(key, input) {
var genKey = genkey(key, 0, 24);
return _btoa(des(genKey.key, input, 1, 1, des3iv, 1)); //小程序中可能會(huì)出現(xiàn)btoa不支持的情況
// return btoa(des(genKey.key, input, 1, 1, des3iv, 1)); //pc手機(jī)
},
////3DES解密,CBC/PKCS5Padding
decrypt: function(key, input) {
var genKey = genkey(key, 0, 24);
return des(genKey.key, atob(input), 0, 1, des3iv, 1);
}
};

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容