Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

简易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>
网名:
34.203.213.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^