Link: http://www.web-tinker.com/article/20710.html
简易SHA1函数(JavaScript实现)
据说MD5目前已经不够安全,通过一些算法很容易制造出具有相同MD5的文件。现在需要更加安全的地方都会使用SHA1+MD5来做验证。这里把SHA1函数也写了个JavaScript的版本,参考了以前VB中的实现。接口依然采用Uint8Array,要用于字符串时需要先转码。不要吐槽没有注释,这个代码是拿来用的,不建议阅读。如果非要有注释的版本,网络上可以找到。
function sha1(data){
/**************************************************
Author:次碳酸钴(admin@web-tinker.com)
Input:Uint8Array
Output:Uint8Array
**************************************************/
var i,j,t;
var l=((data.length+8)>>>6<<4)+16,s=new Uint8Array(l<<2);
s.set(new Uint8Array(data.buffer)),s=new Uint32Array(s.buffer);
for(t=new DataView(s.buffer),i=0;i<l;i++)s[i]=t.getUint32(i<<2);
s[data.length>>2]|=0x80<<(24-(data.length&3)*8);
s[l-1]=data.length<<3;
var w=[],f=[
function(){return m[1]&m[2]|~m[1]&m[3];},
function(){return m[1]^m[2]^m[3];},
function(){return m[1]&m[2]|m[1]&m[3]|m[2]&m[3];},
function(){return m[1]^m[2]^m[3];}
],rol=function(n,c){return n<<c|n>>>(32-c);},
k=[1518500249,1859775393,-1894007588,-899497514],
m=[1732584193,-271733879,null,null,-1009589776];
m[2]=~m[0],m[3]=~m[1];
for(i=0;i<s.length;i+=16){
var o=m.slice(0);
for(j=0;j<80;j++)
w[j]=j<16?s[i+j]:rol(w[j-3]^w[j-8]^w[j-14]^w[j-16],1),
t=rol(m[0],5)+f[j/20|0]()+m[4]+w[j]+k[j/20|0]|0,
m[1]=rol(m[1],30),m.pop(),m.unshift(t);
for(j=0;j<5;j++)m[j]=m[j]+o[j]|0;
};
t=new DataView(new Uint32Array(m).buffer);
for(var i=0;i<5;i++)m[i]=t.getUint32(i<<2);
return new Uint8Array(new Uint32Array(m).buffer);
};
使用演示:
运行<script src="http://www.web-tinker.com/share/sha1.js"></script>
请选择需要计算SHA1的文件:<input type="file" />
<script>
document.querySelector("input").onchange=function(){
var fr=new FileReader;
fr.onload=function(){
var data=new Uint8Array(fr.result);
var result=sha1(data);
var hex=Array.prototype.map.call(result,function(e){
return (e<16?"0":"")+e.toString(16);
}).join("");
document.body.insertAdjacentHTML("beforeend","<p>"+hex+"</p>");
};
fr.readAsArrayBuffer(this.files[0]);
};
</script>
如果需要计算字符串的SHA1,先要将字符串转换为所需的编码,比如
UTF-8:
运行<script src="http://www.web-tinker.com/share/sha1.js"></script>
<textarea>次碳酸钴</textarea><br/>
<input type="button" value="计算文本SHA1(UTF-8)" />
<script>
function encodeUTF8(s){
var i,r=[],c,x;
for(i=0;i<s.length;i++)
if((c=s.charCodeAt(i))<0x80)r.push(c);
else if(c<0x800)r.push(0xC0+(c>>6&0x1F),0x80+(c&0x3F));
else {
if((x=c^0xD800)>>10==0) //对四字节UTF-16转换为Unicode
c=(x<<10)+(s.charCodeAt(++i)^0xDC00)+0x10000,
r.push(0xF0+(c>>18&0x7),0x80+(c>>12&0x3F));
else r.push(0xE0+(c>>12&0xF));
r.push(0x80+(c>>6&0x3F),0x80+(c&0x3F));
};
return r;
};
document.querySelector("input").onclick=function(){
var textarea=document.querySelector("textarea");
var data=new Uint8Array(encodeUTF8(textarea.value));
var result=sha1(data);
var hex=Array.prototype.map.call(result,function(e){
return (e<16?"0":"")+e.toString(16);
}).join("");
document.body.insertAdjacentHTML("beforeend","<p>"+hex+"</p>");
};
</script>