Javascript MD4


Posted in Javascript onDecember 20, 2006

From:http://pajhome.org.uk/crypt/md5/md4src.html

/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD4 Message
 * Digest Algorithm, as defined in RFC 1320.
 * Version 2.1 Copyright (C) Jerrad Pierce, Paul Johnston 1999 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase    */
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance  */
var chrsz  = 8; /* bits per input character. 8 - ASCII; 16 - Unicode   */

/*
 * These are the functions you'll usually want to call
 */
function hex_md4(s){ return binl2hex(core_md4(str2binl(s), s.length * chrsz));}
function b64_md4(s){ return binl2b64(core_md4(str2binl(s), s.length * chrsz));}
function str_md4(s){ return binl2str(core_md4(str2binl(s), s.length * chrsz));}
function hex_hmac_md4(key, data) { return binl2hex(core_hmac_md4(key, data)); }
function b64_hmac_md4(key, data) { return binl2b64(core_hmac_md4(key, data)); }
function str_hmac_md4(key, data) { return binl2str(core_hmac_md4(key, data)); }

/* 
 * Perform a simple self-test to see if the VM is working 
 */
function md4_vm_test()
{
 return hex_md4("abc") == "a448017aaf21d8525fc10ae87aa6729d";
}

/*
 * Calculate the MD4 of an array of little-endian words, and a bit length
 */
function core_md4(x, len)
{
 /* append padding */
 x[len >> 5] |= 0x80 << (len % 32);
 x[(((len + 64) >>> 9) << 4) + 14] = len;
 
 var a = 1732584193;
 var b = -271733879;
 var c = -1732584194;
 var d = 271733878;

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

  a = md4_ff(a, b, c, d, x[i+ 0], 3 );
  d = md4_ff(d, a, b, c, x[i+ 1], 7 );
  c = md4_ff(c, d, a, b, x[i+ 2], 11);
  b = md4_ff(b, c, d, a, x[i+ 3], 19);
  a = md4_ff(a, b, c, d, x[i+ 4], 3 );
  d = md4_ff(d, a, b, c, x[i+ 5], 7 );
  c = md4_ff(c, d, a, b, x[i+ 6], 11);
  b = md4_ff(b, c, d, a, x[i+ 7], 19);
  a = md4_ff(a, b, c, d, x[i+ 8], 3 );
  d = md4_ff(d, a, b, c, x[i+ 9], 7 );
  c = md4_ff(c, d, a, b, x[i+10], 11);
  b = md4_ff(b, c, d, a, x[i+11], 19);
  a = md4_ff(a, b, c, d, x[i+12], 3 );
  d = md4_ff(d, a, b, c, x[i+13], 7 );
  c = md4_ff(c, d, a, b, x[i+14], 11);
  b = md4_ff(b, c, d, a, x[i+15], 19);

  a = md4_gg(a, b, c, d, x[i+ 0], 3 );
  d = md4_gg(d, a, b, c, x[i+ 4], 5 );
  c = md4_gg(c, d, a, b, x[i+ 8], 9 );
  b = md4_gg(b, c, d, a, x[i+12], 13);
  a = md4_gg(a, b, c, d, x[i+ 1], 3 );
  d = md4_gg(d, a, b, c, x[i+ 5], 5 );
  c = md4_gg(c, d, a, b, x[i+ 9], 9 );
  b = md4_gg(b, c, d, a, x[i+13], 13);
  a = md4_gg(a, b, c, d, x[i+ 2], 3 );
  d = md4_gg(d, a, b, c, x[i+ 6], 5 );
  c = md4_gg(c, d, a, b, x[i+10], 9 );
  b = md4_gg(b, c, d, a, x[i+14], 13);
  a = md4_gg(a, b, c, d, x[i+ 3], 3 );
  d = md4_gg(d, a, b, c, x[i+ 7], 5 );
  c = md4_gg(c, d, a, b, x[i+11], 9 );
  b = md4_gg(b, c, d, a, x[i+15], 13);

  a = md4_hh(a, b, c, d, x[i+ 0], 3 );
  d = md4_hh(d, a, b, c, x[i+ 8], 9 );
  c = md4_hh(c, d, a, b, x[i+ 4], 11);
  b = md4_hh(b, c, d, a, x[i+12], 15);
  a = md4_hh(a, b, c, d, x[i+ 2], 3 );
  d = md4_hh(d, a, b, c, x[i+10], 9 );
  c = md4_hh(c, d, a, b, x[i+ 6], 11);
  b = md4_hh(b, c, d, a, x[i+14], 15);
  a = md4_hh(a, b, c, d, x[i+ 1], 3 );
  d = md4_hh(d, a, b, c, x[i+ 9], 9 );
  c = md4_hh(c, d, a, b, x[i+ 5], 11);
  b = md4_hh(b, c, d, a, x[i+13], 15);
  a = md4_hh(a, b, c, d, x[i+ 3], 3 );
  d = md4_hh(d, a, b, c, x[i+11], 9 );
  c = md4_hh(c, d, a, b, x[i+ 7], 11);
  b = md4_hh(b, c, d, a, x[i+15], 15);

  a = safe_add(a, olda);
  b = safe_add(b, oldb);
  c = safe_add(c, oldc);
  d = safe_add(d, oldd);

 }
 return Array(a, b, c, d);

}

/*
 * These functions implement the basic operation for each round of the
 * algorithm.
 */
function md4_cmn(q, a, b, x, s, t)
{
 return safe_add(rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
}
function md4_ff(a, b, c, d, x, s)
{
 return md4_cmn((b & c) | ((~b) & d), a, 0, x, s, 0);
}
function md4_gg(a, b, c, d, x, s)
{
 return md4_cmn((b & c) | (b & d) | (c & d), a, 0, x, s, 1518500249);
}
function md4_hh(a, b, c, d, x, s)
{
 return md4_cmn(b ^ c ^ d, a, 0, x, s, 1859775393);
}

/*
 * Calculate the HMAC-MD4, of a key and some data
 */
function core_hmac_md4(key, data)
{
 var bkey = str2binl(key);
 if(bkey.length > 16) bkey = core_md4(bkey, key.length * chrsz);

 var ipad = Array(16), opad = Array(16);
 for(var i = 0; i < 16; i++) 
 {
  ipad[i] = bkey[i] ^ 0x36363636;
  opad[i] = bkey[i] ^ 0x5C5C5C5C;
 }

 var hash = core_md4(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
 return core_md4(opad.concat(hash), 512 + 128);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
 var lsw = (x & 0xFFFF) + (y & 0xFFFF);
 var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
 return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function rol(num, cnt)
{
 return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert a string to an array of little-endian words
 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
 */
function str2binl(str)
{
 var bin = Array();
 var mask = (1 << chrsz) - 1;
 for(var i = 0; i < str.length * chrsz; i += chrsz)
  bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
 return bin;
}

/*
 * Convert an array of little-endian words to a string
 */
function binl2str(bin)
{
 var str = "";
 var mask = (1 << chrsz) - 1;
 for(var i = 0; i < bin.length * 32; i += chrsz)
  str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
 return str;
}

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray)
{
 var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
 var str = "";
 for(var i = 0; i < binarray.length * 4; i++)
 {
  str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
      hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
 }
 return str;
}

/*
 * Convert an array of little-endian words to a base-64 string
 */
function binl2b64(binarray)
{
 var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 var str = "";
 for(var i = 0; i < binarray.length * 4; i += 3)
 {
  var triplet = (((binarray[i  >> 2] >> 8 * ( i  %4)) & 0xFF) << 16)
        | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
        | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
  for(var j = 0; j < 4; j++)
  {
   if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
   else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
  }
 }
 return str;
}
Javascript 相关文章推荐
JQuery跨Iframe选择实现代码
Aug 19 Javascript
JQuery入门——用bind方法绑定事件处理函数应用介绍
Feb 05 Javascript
JS返回上一页实例代码通过图片和按钮分别实现
Aug 16 Javascript
初识Node.js
Mar 20 Javascript
举例讲解AngularJS中的模块
Jun 17 Javascript
javascript中加var和不加var的区别 你真的懂吗
Jan 06 Javascript
jQuery模拟实现的select点击选择效果【附demo源码下载】
Nov 09 Javascript
React组件的三种写法总结
Jan 12 Javascript
jQuery源码分析之sizzle选择器详解
Feb 13 Javascript
js实现百度登录框鼠标拖拽效果
Mar 07 Javascript
vue使用drag与drop实现拖拽的示例代码
Sep 07 Javascript
封装 axios+promise通用请求函数操作
Aug 11 Javascript
用JavaScript获取网页中的js、css、Flash等文件
Dec 20 #Javascript
取得一定长度的内容,处理中文
Dec 20 #Javascript
解决FLASH需要点击激活的代码
Dec 20 #Javascript
用 JavaScript 迁移目录
Dec 18 #Javascript
Javascript代码混淆综合解决方案-Javascript在线混淆器
Dec 18 #Javascript
XP折叠菜单&amp;仿QQ2006菜单
Dec 16 #Javascript
prototype 1.5相关知识及他人笔记
Dec 16 #Javascript
You might like
php注入实例
2006/10/09 PHP
发款php蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
php目录操作实例代码
2014/02/21 PHP
php实现比较两个文件夹异同的方法
2015/06/18 PHP
PHP模糊查询的实现方法(推荐)
2016/09/06 PHP
laravel 实现上传图片到本地和前台访问示例
2019/10/21 PHP
Jquery实现无刷新DropDownList联动实现代码
2010/03/08 Javascript
javascript采用数组实现tab菜单切换效果
2012/12/12 Javascript
基于JavaScript 声明全局变量的三种方式详解
2013/05/07 Javascript
JS+CSS实现Li列表隔行换色效果的方法
2015/02/16 Javascript
jQuery UI插件自定义confirm确认框的方法
2015/03/20 Javascript
JS或jQuery获取ASP.NET服务器控件ID的方法
2015/06/08 Javascript
js实现下拉列表选中某个值的方法(3种方法)
2015/12/17 Javascript
JavaScript数据类型学习笔记分享
2016/09/01 Javascript
详解基于javascript实现的苹果系统底部菜单
2016/12/02 Javascript
jQuery焦点图左右转换效果
2016/12/12 Javascript
Angular.js实现动态加载组件详解
2017/05/28 Javascript
详解Web使用webpack构建前端项目
2017/09/23 Javascript
微信小程序实现折叠面板
2018/01/31 Javascript
浅谈AngularJS中$http服务的简单用法
2018/05/15 Javascript
nodejs基础之常用工具模块util用法分析
2018/12/26 NodeJs
解决vuex数据页面刷新后初始化操作
2020/07/26 Javascript
Python中的is和id用法分析
2015/01/26 Python
Python使用functools实现注解同步方法
2018/02/06 Python
python opencv实现旋转矩形框裁减功能
2018/07/25 Python
numpy添加新的维度:newaxis的方法
2018/08/02 Python
Python 利用切片从列表中取出一部分使用的方法
2019/02/01 Python
python科学计算之numpy——ufunc函数用法
2019/11/25 Python
带你彻底搞懂python操作mysql数据库(cursor游标讲解)
2020/01/06 Python
浅谈Python中的异常和JSON读写数据的实现
2020/02/27 Python
django 解决自定义序列化返回处理数据为null的问题
2020/05/20 Python
详解pycharm配置python解释器的问题
2020/10/15 Python
交通工程专业推荐信
2014/09/06 职场文书
迟到检讨书
2015/01/26 职场文书
结婚当天新郎保证书
2015/05/08 职场文书
CSS3实现列表无限滚动/轮播效果
2021/06/23 HTML / CSS