/*
 * Código JavaScript del algoritmo Secure Hash Algorithm, SHA-1, como se define
 * en FIPS PUB 180-1
 * Copyright (C) Paul Johnston 2000.
 * Ver http://pajhome.org.uk/site/legal.html para más información.
 * Comentarios traducidos por JMPG01012
 *
 * Ejemplo de uso: resumen=calcSHA1("Cadena a procesar.");
 */

/*
 * Convertir un número de 32-bit a una cadena hexadecimal con ms-byte delante.
 */
var hex_chr="0123456789abcdef";
function hex(num)
{
  var str="";
  for(var j=7; j >= 0; j--)
    str += hex_chr.charAt((num >> (j * 4)) & 0x0F);
  return str;
}

/*
 * Convertir una cadena a secuencia de bloques de 16-word, almacenados como vector.
 * Añade bits de relleno y la longitud, como se describe en la norma SHA1.
 */
function str2blks_SHA1(str)
{
  var nblk=((str.length + 8) >> 6) + 1;
  var blks=new Array(nblk * 16);
  for(var i=0; i < nblk * 16; i++) blks[i]=0;
  for(i=0; i < str.length; i++)
    blks[i >> 2] |= str.charCodeAt(i) << (24 - (i % 4) * 8);
  blks[i >> 2] |= 0x80 << (24 - (i % 4) * 8);
  blks[nblk * 16 - 1]=str.length * 8;
  return blks;
}

/*
 * Suma enteros, recortando en 2^32. Internamente usa opreaciones de 16-bit 
 * para funcionar con los fallos de algunos interpretes JS.
 */
function add(x, y)
{
  var lsw=(x & 0xFFFF) + (y & 0xFFFF);
  var msw=(x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Rota cnt bits a la izquierda un número de 32-bit
 */
function rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Realiza la combinación de triplete adecuada a la iteración actual.
 */
function ft(t, b, c, d)
{
  if(t < 20) return (b & c) | ((~b) & d);
  if(t < 40) return b ^ c ^ d;
  if(t < 60) return (b & c) | (b & d) | (c & d);
  return b ^ c ^ d;
}

/*
 * Determina la constante aditiva correcta para la iteración actual.
 */
function kt(t)
{
  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
         (t < 60) ? -1894007588 : -899497514;
}

/*
 * Toma una cadena y devuelve la representación hexadecimal de su SHA-1.
 */
function calcSHA1(str)
{
  var x=str2blks_SHA1(str);
  var w=new Array(80);

  var a= 1732584193;
  var b=-271733879;
  var c=-1732584194;
  var d= 271733878;
  var e=-1009589776;

  for(var i=0; i < x.length; i += 16)
  {
    var olda=a;
    var oldb=b;
    var oldc=c;
    var oldd=d;
    var olde=e;

    for(var j=0; j < 80; j++)
    {
      if(j < 16) w[j]=x[i + j];
      else w[j]=rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
      t=add(add(rol(a, 5), ft(j, b, c, d)), add(add(e, w[j]), kt(j)));
      e=d;
      d=c;
      c=rol(b, 30);
      b=a;
      a=t;
    }

    a=add(a, olda);
    b=add(b, oldb);
    c=add(c, oldc);
    d=add(d, oldd);
    e=add(e, olde);
  }
  return hex(a) + hex(b) + hex(c) + hex(d) + hex(e);
}
