├── README.md ├── app.js ├── app.json ├── app.wxss ├── pages └── index │ ├── index.js │ ├── index.wxml │ └── index.wxss └── utils ├── .DS_Store ├── aes.js ├── base64.js ├── md5.js └── sha1.js /README.md: -------------------------------------------------------------------------------- 1 | # JS_AESencode 2 | 微信小程序AES加密实现 3 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | onLaunch: function () { 4 | } 5 | }) -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages":[ 3 | "pages/index/index" 4 | ], 5 | "window":{ 6 | "backgroundTextStyle":"light", 7 | "navigationBarBackgroundColor": "#fff", 8 | "navigationBarTitleText": "WeChat", 9 | "navigationBarTextStyle":"black" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | .container { 3 | height: 100%; 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | justify-content: space-between; 8 | padding: 200rpx 0; 9 | box-sizing: border-box; 10 | } 11 | -------------------------------------------------------------------------------- /pages/index/index.js: -------------------------------------------------------------------------------- 1 | //index.js 2 | //获取应用实例 3 | var fun_md5 = require('../../utils/md5.js') 4 | var fun_sha1 = require('../../utils/sha1.js') 5 | var fun_base64 = require('../../utils/base64.js') 6 | var fun_aes = require('../../utils/aes.js') 7 | 8 | var app = getApp() 9 | //十六位十六进制数作为秘钥 10 | var key = fun_aes.CryptoJS.enc.Utf8.parse("5de7e29919fad4d5"); 11 | //十六位十六进制数作为秘钥偏移量 12 | var iv = fun_aes.CryptoJS.enc.Utf8.parse('1234567890123456'); 13 | Page({ 14 | data: { 15 | show_md5: '', 16 | show_sha1: '', 17 | show_base64_encode: '', 18 | show_base64_decode: '', 19 | show_aes_encode: '', 20 | show_aes_decode: '' 21 | }, 22 | onLoad: function () { 23 | //md5加密 24 | var str_md5 = fun_md5.hex_md5("你叫MINA?") 25 | //sha1加密 26 | var str_sha1 = fun_sha1.hex_sha1("你叫MINA?") 27 | var obj_base64 = new fun_base64.Base64(); 28 | //base64加密 29 | var str_base64_encode = obj_base64.encode("你叫MINA?"); 30 | //base64解密 31 | var str_base64_decode = obj_base64.decode(str_base64_encode); 32 | //aes加密 33 | var str_aes_encode = this.Encrypt('空间啊不过快了123485452'); 34 | 35 | var str_aes_encodeBASE64 = this.EncryptBASE64('空间啊不过快了123485452') 36 | //aes解密 37 | var str_aes_decode = this.Decrypt(str_aes_encode); 38 | this.setData({ 39 | show_md5: str_md5, 40 | show_sha1: str_sha1, 41 | show_base64_encode: str_base64_encode, 42 | show_base64_decode: str_base64_decode, 43 | show_aes_encode: str_aes_encode, 44 | show_aes_decode: str_aes_decode, 45 | show_aes_encodebase64: str_aes_encodeBASE64 46 | }) 47 | }, 48 | Encrypt: function (word) { 49 | var srcs = fun_aes.CryptoJS.enc.Utf8.parse(word); 50 | var encrypted = fun_aes.CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: fun_aes.CryptoJS.mode.ECB, padding: fun_aes.CryptoJS.pad.Pkcs7 }); 51 | //返回大写十六进制加密结果 52 | return encrypted.ciphertext.toString().toUpperCase(); 53 | }, 54 | EncryptBASE64: function (word) { 55 | var srcs1 = fun_aes.CryptoJS.enc.Utf8.parse(word); 56 | var encrypted1 = fun_aes.CryptoJS.AES.encrypt(srcs1, key, { iv: iv, mode: fun_aes.CryptoJS.mode.ECB, padding: fun_aes.CryptoJS.pad.Pkcs7 }); 57 | //返回base64加密结果 58 | return encrypted1.toString(); 59 | }, 60 | Decrypt: function (word) { 61 | var encryptedHexStr = fun_aes.CryptoJS.enc.Hex.parse(word); 62 | var srcs = fun_aes.CryptoJS.enc.Base64.stringify(encryptedHexStr); 63 | var decrypt = fun_aes.CryptoJS.AES.decrypt(srcs, key, { iv: iv, mode: fun_aes.CryptoJS.mode.ECB, padding: fun_aes.CryptoJS.pad.Pkcs7 }); 64 | var decryptedStr = decrypt.toString(fun_aes.CryptoJS.enc.Utf8); 65 | return decryptedStr.toString(); 66 | } 67 | }) 68 | -------------------------------------------------------------------------------- /pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 原值:空间啊不过快了123485452 4 | 5 | ECB/128/KEY:5de7e29919fad4d5 6 | 7 | aes加密后16进制: 8 | {{show_aes_encode}} 9 | \n 10 | aes加密后base64: 11 | {{show_aes_encodebase64}} 12 | 13 | aes解密后: 14 | {{show_aes_decode}} 15 | 16 | 17 | -------------------------------------------------------------------------------- /pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | /**index.wxss**/ 2 | .line{ 3 | width: 100%; 4 | height: 5rpx; 5 | background-color: red; 6 | margin: 10rpx; 7 | } 8 | -------------------------------------------------------------------------------- /utils/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eilgnaw/JS_AESencode/b2ae8630554d466904a89a6d07c80e14fa0f20b6/utils/.DS_Store -------------------------------------------------------------------------------- /utils/aes.js: -------------------------------------------------------------------------------- 1 | /* 2 | CryptoJS v3.1.2 3 | code.google.com/p/crypto-js 4 | (c) 2009-2013 by Jeff Mott. All rights reserved. 5 | code.google.com/p/crypto-js/wiki/License 6 | */ 7 | var CryptoJS=CryptoJS||function(u,p){var d={},l=d.lib={},s=function(){},t=l.Base={extend:function(a){s.prototype=this;var c=new s;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, 8 | r=l.WordArray=t.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=p?c:4*a.length},toString:function(a){return(a||v).stringify(this)},concat:function(a){var c=this.words,e=a.words,j=this.sigBytes;a=a.sigBytes;this.clamp();if(j%4)for(var k=0;k>>2]|=(e[k>>>2]>>>24-8*(k%4)&255)<<24-8*((j+k)%4);else if(65535>>2]=e[k>>>2];else c.push.apply(c,e);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< 9 | 32-8*(c%4);a.length=u.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],e=0;e>>2]>>>24-8*(j%4)&255;e.push((k>>>4).toString(16));e.push((k&15).toString(16))}return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j>>3]|=parseInt(a.substr(j, 10 | 2),16)<<24-4*(j%8);return new r.init(e,c/2)}},b=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j>>2]>>>24-8*(j%4)&255));return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j>>2]|=(a.charCodeAt(j)&255)<<24-8*(j%4);return new r.init(e,c)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}}, 11 | q=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,e=c.words,j=c.sigBytes,k=this.blockSize,b=j/(4*k),b=a?u.ceil(b):u.max((b|0)-this._minBufferSize,0);a=b*k;j=u.min(4*a,j);if(a){for(var q=0;q>>2]>>>24-8*(r%4)&255)<<16|(l[r+1>>>2]>>>24-8*((r+1)%4)&255)<<8|l[r+2>>>2]>>>24-8*((r+2)%4)&255,v=0;4>v&&r+0.75*v>>6*(3-v)&63));if(l=t.charAt(64))for(;d.length%4;)d.push(l);return d.join("")},parse:function(d){var l=d.length,s=this._map,t=s.charAt(64);t&&(t=d.indexOf(t),-1!=t&&(l=t));for(var t=[],r=0,w=0;w< 15 | l;w++)if(w%4){var v=s.indexOf(d.charAt(w-1))<<2*(w%4),b=s.indexOf(d.charAt(w))>>>6-2*(w%4);t[r>>>2]|=(v|b)<<24-8*(r%4);r++}return p.create(t,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})(); 16 | (function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b<>>32-j)+n}function d(b,n,a,c,e,j,k){b=b+(n&c|a&~c)+e+k;return(b<>>32-j)+n}function l(b,n,a,c,e,j,k){b=b+(n^a^c)+e+k;return(b<>>32-j)+n}function s(b,n,a,c,e,j,k){b=b+(a^(n|~c))+e+k;return(b<>>32-j)+n}for(var t=CryptoJS,r=t.lib,w=r.WordArray,v=r.Hasher,r=t.algo,b=[],x=0;64>x;x++)b[x]=4294967296*u.abs(u.sin(x+1))|0;r=r.MD5=v.extend({_doReset:function(){this._hash=new w.init([1732584193,4023233417,2562383102,271733878])}, 17 | _doProcessBlock:function(q,n){for(var a=0;16>a;a++){var c=n+a,e=q[c];q[c]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360}var a=this._hash.words,c=q[n+0],e=q[n+1],j=q[n+2],k=q[n+3],z=q[n+4],r=q[n+5],t=q[n+6],w=q[n+7],v=q[n+8],A=q[n+9],B=q[n+10],C=q[n+11],u=q[n+12],D=q[n+13],E=q[n+14],x=q[n+15],f=a[0],m=a[1],g=a[2],h=a[3],f=p(f,m,g,h,c,7,b[0]),h=p(h,f,m,g,e,12,b[1]),g=p(g,h,f,m,j,17,b[2]),m=p(m,g,h,f,k,22,b[3]),f=p(f,m,g,h,z,7,b[4]),h=p(h,f,m,g,r,12,b[5]),g=p(g,h,f,m,t,17,b[6]),m=p(m,g,h,f,w,22,b[7]), 18 | f=p(f,m,g,h,v,7,b[8]),h=p(h,f,m,g,A,12,b[9]),g=p(g,h,f,m,B,17,b[10]),m=p(m,g,h,f,C,22,b[11]),f=p(f,m,g,h,u,7,b[12]),h=p(h,f,m,g,D,12,b[13]),g=p(g,h,f,m,E,17,b[14]),m=p(m,g,h,f,x,22,b[15]),f=d(f,m,g,h,e,5,b[16]),h=d(h,f,m,g,t,9,b[17]),g=d(g,h,f,m,C,14,b[18]),m=d(m,g,h,f,c,20,b[19]),f=d(f,m,g,h,r,5,b[20]),h=d(h,f,m,g,B,9,b[21]),g=d(g,h,f,m,x,14,b[22]),m=d(m,g,h,f,z,20,b[23]),f=d(f,m,g,h,A,5,b[24]),h=d(h,f,m,g,E,9,b[25]),g=d(g,h,f,m,k,14,b[26]),m=d(m,g,h,f,v,20,b[27]),f=d(f,m,g,h,D,5,b[28]),h=d(h,f, 19 | m,g,j,9,b[29]),g=d(g,h,f,m,w,14,b[30]),m=d(m,g,h,f,u,20,b[31]),f=l(f,m,g,h,r,4,b[32]),h=l(h,f,m,g,v,11,b[33]),g=l(g,h,f,m,C,16,b[34]),m=l(m,g,h,f,E,23,b[35]),f=l(f,m,g,h,e,4,b[36]),h=l(h,f,m,g,z,11,b[37]),g=l(g,h,f,m,w,16,b[38]),m=l(m,g,h,f,B,23,b[39]),f=l(f,m,g,h,D,4,b[40]),h=l(h,f,m,g,c,11,b[41]),g=l(g,h,f,m,k,16,b[42]),m=l(m,g,h,f,t,23,b[43]),f=l(f,m,g,h,A,4,b[44]),h=l(h,f,m,g,u,11,b[45]),g=l(g,h,f,m,x,16,b[46]),m=l(m,g,h,f,j,23,b[47]),f=s(f,m,g,h,c,6,b[48]),h=s(h,f,m,g,w,10,b[49]),g=s(g,h,f,m, 20 | E,15,b[50]),m=s(m,g,h,f,r,21,b[51]),f=s(f,m,g,h,u,6,b[52]),h=s(h,f,m,g,k,10,b[53]),g=s(g,h,f,m,B,15,b[54]),m=s(m,g,h,f,e,21,b[55]),f=s(f,m,g,h,v,6,b[56]),h=s(h,f,m,g,x,10,b[57]),g=s(g,h,f,m,t,15,b[58]),m=s(m,g,h,f,D,21,b[59]),f=s(f,m,g,h,z,6,b[60]),h=s(h,f,m,g,C,10,b[61]),g=s(g,h,f,m,j,15,b[62]),m=s(m,g,h,f,A,21,b[63]);a[0]=a[0]+f|0;a[1]=a[1]+m|0;a[2]=a[2]+g|0;a[3]=a[3]+h|0},_doFinalize:function(){var b=this._data,n=b.words,a=8*this._nDataBytes,c=8*b.sigBytes;n[c>>>5]|=128<<24-c%32;var e=u.floor(a/ 21 | 4294967296);n[(c+64>>>9<<4)+15]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360;n[(c+64>>>9<<4)+14]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4*(n.length+1);this._process();b=this._hash;n=b.words;for(a=0;4>a;a++)c=n[a],n[a]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360;return b},clone:function(){var b=v.clone.call(this);b._hash=this._hash.clone();return b}});t.MD5=v._createHelper(r);t.HmacMD5=v._createHmacHelper(r)})(Math); 22 | (function(){var u=CryptoJS,p=u.lib,d=p.Base,l=p.WordArray,p=u.algo,s=p.EvpKDF=d.extend({cfg:d.extend({keySize:4,hasher:p.MD5,iterations:1}),init:function(d){this.cfg=this.cfg.extend(d)},compute:function(d,r){for(var p=this.cfg,s=p.hasher.create(),b=l.create(),u=b.words,q=p.keySize,p=p.iterations;u.length>>2]&255}};d.BlockCipher=v.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var c=a.createEncryptor;else c=a.createDecryptor,this._minBufferSize=1;this._mode=c.call(a, 28 | this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var n=d.CipherParams=l.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b=(p.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a=a.salt;return(a?s.create([1398893684, 29 | 1701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){a=r.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var c=s.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return n.create({ciphertext:a,salt:c})}},a=d.SerializableCipher=l.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){d=this.cfg.extend(d);var l=a.createEncryptor(c,d);b=l.finalize(b);l=l.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})}, 30 | decrypt:function(a,b,c,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),p=(p.kdf={}).OpenSSL={execute:function(a,b,c,d){d||(d=s.random(8));a=w.create({keySize:b+c}).compute(a,d);c=s.create(a.words.slice(b),4*c);a.sigBytes=4*b;return n.create({key:a,iv:c,salt:d})}},c=d.PasswordBasedCipher=a.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){l=this.cfg.extend(l);d=l.kdf.execute(d, 31 | b.keySize,b.ivSize);l.iv=d.iv;b=a.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){l=this.cfg.extend(l);c=this._parse(c,l.format);d=l.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.iv=d.iv;return a.decrypt.call(this,b,c,d.key,l)}})}(); 32 | (function(){for(var u=CryptoJS,p=u.lib.BlockCipher,d=u.algo,l=[],s=[],t=[],r=[],w=[],v=[],b=[],x=[],q=[],n=[],a=[],c=0;256>c;c++)a[c]=128>c?c<<1:c<<1^283;for(var e=0,j=0,c=0;256>c;c++){var k=j^j<<1^j<<2^j<<3^j<<4,k=k>>>8^k&255^99;l[e]=k;s[k]=e;var z=a[e],F=a[z],G=a[F],y=257*a[k]^16843008*k;t[e]=y<<24|y>>>8;r[e]=y<<16|y>>>16;w[e]=y<<8|y>>>24;v[e]=y;y=16843009*G^65537*F^257*z^16843008*e;b[k]=y<<24|y>>>8;x[k]=y<<16|y>>>16;q[k]=y<<8|y>>>24;n[k]=y;e?(e=z^a[a[a[G^z]]],j^=a[a[j]]):e=j=1}var H=[0,1,2,4,8, 33 | 16,32,64,128,27,54],d=d.AES=p.extend({_doReset:function(){for(var a=this._key,c=a.words,d=a.sigBytes/4,a=4*((this._nRounds=d+6)+1),e=this._keySchedule=[],j=0;j>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255]):(k=k<<8|k>>>24,k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255],k^=H[j/d|0]<<24);e[j]=e[j-d]^k}c=this._invKeySchedule=[];for(d=0;dd||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>> 34 | 8&255]]^n[l[k&255]]},encryptBlock:function(a,b){this._doCryptBlock(a,b,this._keySchedule,t,r,w,v,l)},decryptBlock:function(a,c){var d=a[c+1];a[c+1]=a[c+3];a[c+3]=d;this._doCryptBlock(a,c,this._invKeySchedule,b,x,q,n,s);d=a[c+1];a[c+1]=a[c+3];a[c+3]=d},_doCryptBlock:function(a,b,c,d,e,j,l,f){for(var m=this._nRounds,g=a[b]^c[0],h=a[b+1]^c[1],k=a[b+2]^c[2],n=a[b+3]^c[3],p=4,r=1;r>>24]^e[h>>>16&255]^j[k>>>8&255]^l[n&255]^c[p++],s=d[h>>>24]^e[k>>>16&255]^j[n>>>8&255]^l[g&255]^c[p++],t= 35 | d[k>>>24]^e[n>>>16&255]^j[g>>>8&255]^l[h&255]^c[p++],n=d[n>>>24]^e[g>>>16&255]^j[h>>>8&255]^l[k&255]^c[p++],g=q,h=s,k=t;q=(f[g>>>24]<<24|f[h>>>16&255]<<16|f[k>>>8&255]<<8|f[n&255])^c[p++];s=(f[h>>>24]<<24|f[k>>>16&255]<<16|f[n>>>8&255]<<8|f[g&255])^c[p++];t=(f[k>>>24]<<24|f[n>>>16&255]<<16|f[g>>>8&255]<<8|f[h&255])^c[p++];n=(f[n>>>24]<<24|f[g>>>16&255]<<16|f[h>>>8&255]<<8|f[k&255])^c[p++];a[b]=q;a[b+1]=s;a[b+2]=t;a[b+3]=n},keySize:8});u.AES=p._createHelper(d)})(); 36 | CryptoJS.mode.ECB = (function () { 37 | var ECB = CryptoJS.lib.BlockCipherMode.extend(); 38 | 39 | ECB.Encryptor = ECB.extend({ 40 | processBlock: function (words, offset) { 41 | this._cipher.encryptBlock(words, offset); 42 | } 43 | }); 44 | 45 | ECB.Decryptor = ECB.extend({ 46 | processBlock: function (words, offset) { 47 | this._cipher.decryptBlock(words, offset); 48 | } 49 | }); 50 | 51 | return ECB; 52 | }()); 53 | module.exports = { 54 | CryptoJS: CryptoJS 55 | } -------------------------------------------------------------------------------- /utils/base64.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Base64 encode / decode 4 | * 5 | * @author haitao.tu 6 | * @date 2010-04-26 7 | * @email tuhaitao@foxmail.com 8 | * 9 | */ 10 | 11 | function Base64() { 12 | 13 | // private property 14 | var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 15 | 16 | // public method for encoding 17 | this.encode = function (input) { 18 | var output = ""; 19 | var chr1, chr2, chr3, enc1, enc2, enc3, enc4; 20 | var i = 0; 21 | input = _utf8_encode(input); 22 | while (i < input.length) { 23 | chr1 = input.charCodeAt(i++); 24 | chr2 = input.charCodeAt(i++); 25 | chr3 = input.charCodeAt(i++); 26 | enc1 = chr1 >> 2; 27 | enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 28 | enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 29 | enc4 = chr3 & 63; 30 | if (isNaN(chr2)) { 31 | enc3 = enc4 = 64; 32 | } else if (isNaN(chr3)) { 33 | enc4 = 64; 34 | } 35 | output = output + 36 | _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + 37 | _keyStr.charAt(enc3) + _keyStr.charAt(enc4); 38 | } 39 | return output; 40 | } 41 | 42 | // public method for decoding 43 | this.decode = function (input) { 44 | var output = ""; 45 | var chr1, chr2, chr3; 46 | var enc1, enc2, enc3, enc4; 47 | var i = 0; 48 | input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 49 | while (i < input.length) { 50 | enc1 = _keyStr.indexOf(input.charAt(i++)); 51 | enc2 = _keyStr.indexOf(input.charAt(i++)); 52 | enc3 = _keyStr.indexOf(input.charAt(i++)); 53 | enc4 = _keyStr.indexOf(input.charAt(i++)); 54 | chr1 = (enc1 << 2) | (enc2 >> 4); 55 | chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); 56 | chr3 = ((enc3 & 3) << 6) | enc4; 57 | output = output + String.fromCharCode(chr1); 58 | if (enc3 != 64) { 59 | output = output + String.fromCharCode(chr2); 60 | } 61 | if (enc4 != 64) { 62 | output = output + String.fromCharCode(chr3); 63 | } 64 | } 65 | output = _utf8_decode(output); 66 | return output; 67 | } 68 | 69 | // private method for UTF-8 encoding 70 | var _utf8_encode = function (string) { 71 | string = string.replace(/\r\n/g,"\n"); 72 | var utftext = ""; 73 | for (var n = 0; n < string.length; n++) { 74 | var c = string.charCodeAt(n); 75 | if (c < 128) { 76 | utftext += String.fromCharCode(c); 77 | } else if((c > 127) && (c < 2048)) { 78 | utftext += String.fromCharCode((c >> 6) | 192); 79 | utftext += String.fromCharCode((c & 63) | 128); 80 | } else { 81 | utftext += String.fromCharCode((c >> 12) | 224); 82 | utftext += String.fromCharCode(((c >> 6) & 63) | 128); 83 | utftext += String.fromCharCode((c & 63) | 128); 84 | } 85 | 86 | } 87 | return utftext; 88 | } 89 | 90 | // private method for UTF-8 decoding 91 | var _utf8_decode = function (utftext) { 92 | var string = ""; 93 | var i = 0; 94 | var c =0; 95 | var c1 = 0; 96 | var c2 = 0; 97 | var c3 = 0; 98 | while ( i < utftext.length ) { 99 | c = utftext.charCodeAt(i); 100 | if (c < 128) { 101 | string += String.fromCharCode(c); 102 | i++; 103 | } else if((c > 191) && (c < 224)) { 104 | c2 = utftext.charCodeAt(i+1); 105 | string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); 106 | i += 2; 107 | } else { 108 | c2 = utftext.charCodeAt(i+1); 109 | c3 = utftext.charCodeAt(i+2); 110 | string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); 111 | i += 3; 112 | } 113 | } 114 | return string; 115 | } 116 | } 117 | 118 | module.exports = { 119 | Base64: Base64 120 | } -------------------------------------------------------------------------------- /utils/md5.js: -------------------------------------------------------------------------------- 1 | /* 2 | * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message 3 | * Digest Algorithm, as defined in RFC 1321. 4 | * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. 5 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 6 | * Distributed under the BSD License 7 | * See http://pajhome.org.uk/crypt/md5 for more info. 8 | */ 9 | 10 | /* 11 | * Configurable variables. You may need to tweak these to be compatible with 12 | * the server-side, but the defaults work in most cases. 13 | */ 14 | var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ 15 | var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ 16 | var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ 17 | 18 | /* 19 | * These are the functions you'll usually want to call 20 | * They take string arguments and return either hex or base-64 encoded strings 21 | */ 22 | function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} 23 | function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));} 24 | function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));} 25 | function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); } 26 | function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); } 27 | function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); } 28 | 29 | /* 30 | * Perform a simple self-test to see if the VM is working 31 | */ 32 | function md5_vm_test() 33 | { 34 | return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; 35 | } 36 | 37 | /* 38 | * Calculate the MD5 of an array of little-endian words, and a bit length 39 | */ 40 | function core_md5(x, len) 41 | { 42 | /* append padding */ 43 | x[len >> 5] |= 0x80 << ((len) % 32); 44 | x[(((len + 64) >>> 9) << 4) + 14] = len; 45 | 46 | var a = 1732584193; 47 | var b = -271733879; 48 | var c = -1732584194; 49 | var d = 271733878; 50 | 51 | for(var i = 0; i < x.length; i += 16) 52 | { 53 | var olda = a; 54 | var oldb = b; 55 | var oldc = c; 56 | var oldd = d; 57 | 58 | a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); 59 | d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); 60 | c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); 61 | b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); 62 | a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); 63 | d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); 64 | c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); 65 | b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); 66 | a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); 67 | d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); 68 | c = md5_ff(c, d, a, b, x[i+10], 17, -42063); 69 | b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); 70 | a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); 71 | d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); 72 | c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); 73 | b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); 74 | 75 | a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); 76 | d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); 77 | c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); 78 | b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); 79 | a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); 80 | d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); 81 | c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); 82 | b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); 83 | a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); 84 | d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); 85 | c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); 86 | b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); 87 | a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); 88 | d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); 89 | c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); 90 | b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); 91 | 92 | a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); 93 | d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); 94 | c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); 95 | b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); 96 | a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); 97 | d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); 98 | c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); 99 | b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); 100 | a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); 101 | d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); 102 | c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); 103 | b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); 104 | a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); 105 | d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); 106 | c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); 107 | b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); 108 | 109 | a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); 110 | d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); 111 | c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); 112 | b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); 113 | a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); 114 | d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); 115 | c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); 116 | b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); 117 | a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); 118 | d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); 119 | c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); 120 | b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); 121 | a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); 122 | d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); 123 | c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); 124 | b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); 125 | 126 | a = safe_add(a, olda); 127 | b = safe_add(b, oldb); 128 | c = safe_add(c, oldc); 129 | d = safe_add(d, oldd); 130 | } 131 | return Array(a, b, c, d); 132 | 133 | } 134 | 135 | /* 136 | * These functions implement the four basic operations the algorithm uses. 137 | */ 138 | function md5_cmn(q, a, b, x, s, t) 139 | { 140 | return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); 141 | } 142 | function md5_ff(a, b, c, d, x, s, t) 143 | { 144 | return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); 145 | } 146 | function md5_gg(a, b, c, d, x, s, t) 147 | { 148 | return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); 149 | } 150 | function md5_hh(a, b, c, d, x, s, t) 151 | { 152 | return md5_cmn(b ^ c ^ d, a, b, x, s, t); 153 | } 154 | function md5_ii(a, b, c, d, x, s, t) 155 | { 156 | return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); 157 | } 158 | 159 | /* 160 | * Calculate the HMAC-MD5, of a key and some data 161 | */ 162 | function core_hmac_md5(key, data) 163 | { 164 | var bkey = str2binl(key); 165 | if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); 166 | 167 | var ipad = Array(16), opad = Array(16); 168 | for(var i = 0; i < 16; i++) 169 | { 170 | ipad[i] = bkey[i] ^ 0x36363636; 171 | opad[i] = bkey[i] ^ 0x5C5C5C5C; 172 | } 173 | 174 | var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); 175 | return core_md5(opad.concat(hash), 512 + 128); 176 | } 177 | 178 | /* 179 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally 180 | * to work around bugs in some JS interpreters. 181 | */ 182 | function safe_add(x, y) 183 | { 184 | var lsw = (x & 0xFFFF) + (y & 0xFFFF); 185 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 186 | return (msw << 16) | (lsw & 0xFFFF); 187 | } 188 | 189 | /* 190 | * Bitwise rotate a 32-bit number to the left. 191 | */ 192 | function bit_rol(num, cnt) 193 | { 194 | return (num << cnt) | (num >>> (32 - cnt)); 195 | } 196 | 197 | /* 198 | * Convert a string to an array of little-endian words 199 | * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. 200 | */ 201 | function str2binl(str) 202 | { 203 | var bin = Array(); 204 | var mask = (1 << chrsz) - 1; 205 | for(var i = 0; i < str.length * chrsz; i += chrsz) 206 | bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); 207 | return bin; 208 | } 209 | 210 | /* 211 | * Convert an array of little-endian words to a string 212 | */ 213 | function binl2str(bin) 214 | { 215 | var str = ""; 216 | var mask = (1 << chrsz) - 1; 217 | for(var i = 0; i < bin.length * 32; i += chrsz) 218 | str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); 219 | return str; 220 | } 221 | 222 | /* 223 | * Convert an array of little-endian words to a hex string. 224 | */ 225 | function binl2hex(binarray) 226 | { 227 | var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; 228 | var str = ""; 229 | for(var i = 0; i < binarray.length * 4; i++) 230 | { 231 | str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + 232 | hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF); 233 | } 234 | return str; 235 | } 236 | 237 | /* 238 | * Convert an array of little-endian words to a base-64 string 239 | */ 240 | function binl2b64(binarray) 241 | { 242 | var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 243 | var str = ""; 244 | for(var i = 0; i < binarray.length * 4; i += 3) 245 | { 246 | var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16) 247 | | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) 248 | | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF); 249 | for(var j = 0; j < 4; j++) 250 | { 251 | if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; 252 | else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); 253 | } 254 | } 255 | return str; 256 | } 257 | 258 | module.exports = { 259 | hex_md5: hex_md5 260 | } 261 | -------------------------------------------------------------------------------- /utils/sha1.js: -------------------------------------------------------------------------------- 1 | /* 2 | * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined 3 | * in FIPS PUB 180-1 4 | * Version 2.1-BETA Copyright Paul Johnston 2000 - 2002. 5 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 6 | * Distributed under the BSD License 7 | * See http://pajhome.org.uk/crypt/md5 for details. 8 | */ 9 | /* 10 | * Configurable variables. You may need to tweak these to be compatible with 11 | * the server-side, but the defaults work in most cases. 12 | */ 13 | var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ 14 | var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ 15 | var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ 16 | 17 | /* 18 | * These are the functions you'll usually want to call 19 | * They take string arguments and return either hex or base-64 encoded strings 20 | */ 21 | function hex_sha1(s) { 22 | return binb2hex(core_sha1(str2binb(s), s.length * chrsz)); 23 | } 24 | 25 | function b64_sha1(s) { 26 | return binb2b64(core_sha1(str2binb(s), s.length * chrsz)); 27 | } 28 | 29 | function str_sha1(s) { 30 | return binb2str(core_sha1(str2binb(s), s.length * chrsz)); 31 | } 32 | 33 | function hex_hmac_sha1(key, data) { 34 | return binb2hex(core_hmac_sha1(key, data)); 35 | } 36 | 37 | function b64_hmac_sha1(key, data) { 38 | return binb2b64(core_hmac_sha1(key, data)); 39 | } 40 | 41 | function str_hmac_sha1(key, data) { 42 | return binb2str(core_hmac_sha1(key, data)); 43 | } 44 | 45 | /* 46 | * Perform a simple self-test to see if the VM is working 47 | */ 48 | function sha1_vm_test() { 49 | return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d"; 50 | } 51 | 52 | /* 53 | * Calculate the SHA-1 of an array of big-endian words, and a bit length 54 | */ 55 | function core_sha1(x, len) { 56 | /* append padding */ 57 | x[len >> 5] |= 0x80 << (24 - len % 32); 58 | x[((len + 64 >> 9) << 4) + 15] = len; 59 | 60 | var w = Array(80); 61 | var a = 1732584193; 62 | var b = -271733879; 63 | var c = -1732584194; 64 | var d = 271733878; 65 | var e = -1009589776; 66 | 67 | for (var i = 0; i < x.length; i += 16) { 68 | var olda = a; 69 | var oldb = b; 70 | var oldc = c; 71 | var oldd = d; 72 | var olde = e; 73 | 74 | for (var j = 0; j < 80; j++) { 75 | if (j < 16) w[j] = x[i + j]; 76 | else w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); 77 | var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j))); 78 | e = d; 79 | d = c; 80 | c = rol(b, 30); 81 | b = a; 82 | a = t; 83 | } 84 | 85 | a = safe_add(a, olda); 86 | b = safe_add(b, oldb); 87 | c = safe_add(c, oldc); 88 | d = safe_add(d, oldd); 89 | e = safe_add(e, olde); 90 | } 91 | return Array(a, b, c, d, e); 92 | 93 | } 94 | 95 | /* 96 | * Perform the appropriate triplet combination function for the current 97 | * iteration 98 | */ 99 | function sha1_ft(t, b, c, d) { 100 | if (t < 20) return (b & c) | ((~b) & d); 101 | if (t < 40) return b ^ c ^ d; 102 | if (t < 60) return (b & c) | (b & d) | (c & d); 103 | return b ^ c ^ d; 104 | } 105 | 106 | /* 107 | * Determine the appropriate additive constant for the current iteration 108 | */ 109 | function sha1_kt(t) { 110 | return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514; 111 | } 112 | 113 | /* 114 | * Calculate the HMAC-SHA1 of a key and some data 115 | */ 116 | function core_hmac_sha1(key, data) { 117 | var bkey = str2binb(key); 118 | if (bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz); 119 | 120 | var ipad = Array(16), 121 | opad = Array(16); 122 | for (var i = 0; i < 16; i++) { 123 | ipad[i] = bkey[i] ^ 0x36363636; 124 | opad[i] = bkey[i] ^ 0x5C5C5C5C; 125 | } 126 | 127 | var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz); 128 | return core_sha1(opad.concat(hash), 512 + 160); 129 | } 130 | 131 | /* 132 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally 133 | * to work around bugs in some JS interpreters. 134 | */ 135 | function safe_add(x, y) { 136 | var lsw = (x & 0xFFFF) + (y & 0xFFFF); 137 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 138 | return (msw << 16) | (lsw & 0xFFFF); 139 | } 140 | 141 | /* 142 | * Bitwise rotate a 32-bit number to the left. 143 | */ 144 | function rol(num, cnt) { 145 | return (num << cnt) | (num >>> (32 - cnt)); 146 | } 147 | 148 | /* 149 | * Convert an 8-bit or 16-bit string to an array of big-endian words 150 | * In 8-bit function, characters >255 have their hi-byte silently ignored. 151 | */ 152 | function str2binb(str) { 153 | var bin = Array(); 154 | var mask = (1 << chrsz) - 1; 155 | for (var i = 0; i < str.length * chrsz; i += chrsz) 156 | bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i % 32); 157 | return bin; 158 | } 159 | 160 | /* 161 | * Convert an array of big-endian words to a string 162 | */ 163 | function binb2str(bin) { 164 | var str = ""; 165 | var mask = (1 << chrsz) - 1; 166 | for (var i = 0; i < bin.length * 32; i += chrsz) 167 | str += String.fromCharCode((bin[i >> 5] >>> (24 - i % 32)) & mask); 168 | return str; 169 | } 170 | 171 | /* 172 | * Convert an array of big-endian words to a hex string. 173 | */ 174 | function binb2hex(binarray) { 175 | var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; 176 | var str = ""; 177 | for (var i = 0; i < binarray.length * 4; i++) { 178 | str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) + hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF); 179 | } 180 | return str; 181 | } 182 | 183 | /* 184 | * Convert an array of big-endian words to a base-64 string 185 | */ 186 | function binb2b64(binarray) { 187 | var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 188 | var str = ""; 189 | for (var i = 0; i < binarray.length * 4; i += 3) { 190 | var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) | (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) | ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF); 191 | for (var j = 0; j < 4; j++) { 192 | if (i * 8 + j * 6 > binarray.length * 32) str += b64pad; 193 | else str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F); 194 | } 195 | } 196 | return str; 197 | } 198 | 199 | module.exports = { 200 | hex_sha1: hex_sha1 201 | } 202 | --------------------------------------------------------------------------------