📄 blowfish.js
字号:
for(var i=0; i < box.p.length; i++){ for (var j=0; j<4; j++){ data = (data*POW8) | k[pos]; if(++pos==k.length) pos=0; } box.p[i] = xor(box.p[i], data); } // encrypt p and the s boxes var res={ left:0, right:0 }; for(var i=0; i<box.p.length;){ eb(res, box); box.p[i++]=res.left; box.p[i++]=res.right; } for (var i=0; i<4; i++){ for(var j=0; j<box["s"+i].length;){ eb(res, box); box["s"+i][j++]=res.left; box["s"+i][j++]=res.right; } } return box; }////////////////////////////////////////////////////////////////////////////// CONVERSION FUNCTIONS//////////////////////////////////////////////////////////////////////////// // these operate on byte arrays, NOT word arrays. function toBase64(ba){ var p="="; var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var s=[]; var count=0; for (var i =0; i<ba.length;){ var t=ba[i++]<<16|ba[i++]<<8|ba[i++]; s.push(tab.charAt((t>>>18)&0x3f)); s.push(tab.charAt((t>>>12)&0x3f)); s.push(tab.charAt((t>>>6)&0x3f)); s.push(tab.charAt(t&0x3f)); count+=4; } var pa=i-ba.length; while((pa--)>0) s.push(p); return s.join(""); } function fromBase64(str){ var s=str.split(""); var p="="; var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var out=[]; var l=s.length; while(s[--l]==p){ } for (var i=0; i<l;){ var t=tab.indexOf(s[i++])<<18|tab.indexOf(s[i++])<<12|tab.indexOf(s[i++])<<6|tab.indexOf(s[i++]); out.push((t>>>16)&0xff); out.push((t>>>8)&0xff); out.push(t&0xff); } return out; }////////////////////////////////////////////////////////////////////////////// PUBLIC FUNCTIONS// 0.2: Only supporting ECB mode for now.//////////////////////////////////////////////////////////////////////////// this.getIV=function(outputType){ var out=outputType||dojo.crypto.outputTypes.Base64; switch(out){ case dojo.crypto.outputTypes.Hex:{ var s=[]; for(var i=0; i<iv.length; i++) s.push((iv[i]).toString(16)); return s.join(""); } case dojo.crypto.outputTypes.String:{ return iv.join(""); } case dojo.crypto.outputTypes.Raw:{ return iv; } default:{ return toBase64(iv); } } }; this.setIV=function(data, inputType){ var ip=inputType||dojo.crypto.outputTypes.Base64; var ba=null; switch(ip){ case dojo.crypto.outputTypes.String:{ ba=[]; for (var i=0; i<data.length; i++){ ba.push(data.charCodeAt(i)); } break; } case dojo.crypto.outputTypes.Hex:{ ba=[]; var i=0; while (i+1<data.length){ ba.push(parseInt(data.substr(i,2),16)); i+=2; } break; } case dojo.crypto.outputTypes.Raw:{ ba=data; break; } default:{ ba=fromBase64(data); break; } } // make it a pair of words now iv={}; iv.left=ba[0]*POW24|ba[1]*POW16|ba[2]*POW8|ba[3]; iv.right=ba[4]*POW24|ba[5]*POW16|ba[6]*POW8|ba[7]; } this.encrypt = function(plaintext, key, ao){ var out=dojo.crypto.outputTypes.Base64; var mode=dojo.crypto.cipherModes.EBC; if (ao){ if (ao.outputType) out=ao.outputType; if (ao.cipherMode) mode=ao.cipherMode; } var bx = init(key); var padding = 8-(plaintext.length&7); for (var i=0; i<padding; i++) plaintext+=String.fromCharCode(padding); var cipher=[]; var count=plaintext.length >> 3; var pos=0; var o={}; var isCBC=(mode==dojo.crypto.cipherModes.CBC); var vector={left:iv.left||null, right:iv.right||null}; for(var i=0; i<count; i++){ o.left=plaintext.charCodeAt(pos)*POW24 |plaintext.charCodeAt(pos+1)*POW16 |plaintext.charCodeAt(pos+2)*POW8 |plaintext.charCodeAt(pos+3); o.right=plaintext.charCodeAt(pos+4)*POW24 |plaintext.charCodeAt(pos+5)*POW16 |plaintext.charCodeAt(pos+6)*POW8 |plaintext.charCodeAt(pos+7); if(isCBC){ o.left=xor(o.left, vector.left); o.right=xor(o.right, vector.right); } eb(o, bx); // encrypt the block if(isCBC){ vector.left=o.left; vector.right=o.right;dojo.crypto.outputTypes.Hex } cipher.push((o.left>>24)&0xff); cipher.push((o.left>>16)&0xff); cipher.push((o.left>>8)&0xff); cipher.push(o.left&0xff); cipher.push((o.right>>24)&0xff); cipher.push((o.right>>16)&0xff); cipher.push((o.right>>8)&0xff); cipher.push(o.right&0xff); pos+=8; } switch(out){ case dojo.crypto.outputTypes.Hex:{ var s=[]; for(var i=0; i<cipher.length; i++) s.push((cipher[i]).toString(16)); return s.join(""); } case dojo.crypto.outputTypes.String:{ return cipher.join(""); } case dojo.crypto.outputTypes.Raw:{ return cipher; } default:{ return toBase64(cipher); } } }; this.decrypt = function(ciphertext, key, ao){ var ip=dojo.crypto.outputTypes.Base64; var mode=dojo.crypto.cipherModes.EBC; if (ao){ if (ao.outputType) ip=ao.outputType; if (ao.cipherMode) mode=ao.cipherMode; } var bx = init(key); var pt=[]; var c=null; switch(ip){ case dojo.crypto.outputTypes.Hex:{ c=[]; var i=0; while (i+1<ciphertext.length){ c.push(parseInt(ciphertext.substr(i,2),16)); i+=2; } break; } case dojo.crypto.outputTypes.String:{ c=[]; for (var i=0; i<ciphertext.length; i++){ c.push(ciphertext.charCodeAt(i)); } break; } case dojo.crypto.outputTypes.Raw:{ c=ciphertext; // should be a byte array break; } default:{ c=fromBase64(ciphertext); break; } } var count=c.length >> 3; var pos=0; var o={}; var isCBC=(mode==dojo.crypto.cipherModes.CBC); var vector={left:iv.left||null, right:iv.right||null}; for(var i=0; i<count; i++){ o.left=c[pos]*POW24|c[pos+1]*POW16|c[pos+2]*POW8|c[pos+3]; o.right=c[pos+4]*POW24|c[pos+5]*POW16|c[pos+6]*POW8|c[pos+7]; if(isCBC){ var left=o.left; var right=o.right; } db(o, bx); // decrypt the block if(isCBC){ o.left=xor(o.left, vector.left); o.right=xor(o.right, vector.right); vector.left=left; vector.right=right; } pt.push((o.left>>24)&0xff); pt.push((o.left>>16)&0xff); pt.push((o.left>>8)&0xff); pt.push(o.left&0xff); pt.push((o.right>>24)&0xff); pt.push((o.right>>16)&0xff); pt.push((o.right>>8)&0xff); pt.push(o.right&0xff); pos+=8; } // check for padding, and remove. if(pt[pt.length-1]==pt[pt.length-2]||pt[pt.length-1]==0x01){ var n=pt[pt.length-1]; pt.splice(pt.length-n, n); } // convert to string for(var i=0; i<pt.length; i++) pt[i]=String.fromCharCode(pt[i]); return pt.join(""); }; this.setIV("0000000000000000", dojo.crypto.outputTypes.Hex);}();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -