4 * An ActionScript 3 implementation of the RSA Data Security, Inc. MD5 Message
\r
5 * Digest Algorithm, as defined in RFC 1321.
\r
6 * Copyright (c) 2007 Henri Torgemane
\r
9 * A JavaScript implementation of the same.
\r
10 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
\r
11 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
\r
14 * This algorithm should not be your first choice for new developements, but is
\r
15 * included to allow interoperability with existing codes and protocols.
\r
17 * See LICENSE.txt for full license information.
\r
19 package com.hurlant.crypto.hash
\r
21 import flash.utils.ByteArray;
\r
22 import flash.utils.Endian;
\r
24 public class MD5 implements IHash
\r
26 public static const HASH_SIZE:int = 16;
\r
27 public var pad_size:int = 48;
\r
29 public function MD5() { }
\r
31 public function getInputSize():uint
\r
36 public function getHashSize():uint
\r
41 public function getPadSize():int
\r
46 public function hash(src:ByteArray):ByteArray
\r
48 var len:uint = src.length *8;
\r
49 var savedEndian:String = src.endian;
\r
50 // pad to nearest int.
\r
51 while (src.length%4!=0) {
\r
54 // convert ByteArray to an array of uint
\r
57 src.endian=Endian.LITTLE_ENDIAN
\r
58 for (var i:uint=0;i<src.length;i+=4) {
\r
59 a.push(src.readUnsignedInt());
\r
61 var h:Array = core_md5(a, len);
\r
62 var out:ByteArray = new ByteArray;
\r
63 out.endian=Endian.LITTLE_ENDIAN;
\r
65 out.writeUnsignedInt(h[i]);
\r
69 src.endian = savedEndian;
\r
74 private function core_md5(x:Array, len:uint):Array {
\r
75 /* append padding */
\r
76 x[len >> 5] |= 0x80 << ((len) % 32);
\r
77 x[(((len + 64) >>> 9) << 4) + 14] = len;
\r
79 var a:uint = 0x67452301; // 1732584193;
\r
80 var b:uint = 0xEFCDAB89; //-271733879;
\r
81 var c:uint = 0x98BADCFE; //-1732584194;
\r
82 var d:uint = 0x10325476; // 271733878;
\r
84 for(var i:uint = 0; i < x.length; i += 16)
\r
86 x[i]||=0; x[i+1]||=0; x[i+2]||=0; x[i+3]||=0;
\r
87 x[i+4]||=0; x[i+5]||=0; x[i+6]||=0; x[i+7]||=0;
\r
88 x[i+8]||=0; x[i+9]||=0; x[i+10]||=0; x[i+11]||=0;
\r
89 x[i+12]||=0; x[i+13]||=0; x[i+14]||=0; x[i+15]||=0;
\r
96 a = ff(a, b, c, d, x[i+ 0], 7 , 0xD76AA478);
\r
97 d = ff(d, a, b, c, x[i+ 1], 12, 0xE8C7B756);
\r
98 c = ff(c, d, a, b, x[i+ 2], 17, 0x242070DB);
\r
99 b = ff(b, c, d, a, x[i+ 3], 22, 0xC1BDCEEE);
\r
100 a = ff(a, b, c, d, x[i+ 4], 7 , 0xF57C0FAF);
\r
101 d = ff(d, a, b, c, x[i+ 5], 12, 0x4787C62A);
\r
102 c = ff(c, d, a, b, x[i+ 6], 17, 0xA8304613);
\r
103 b = ff(b, c, d, a, x[i+ 7], 22, 0xFD469501);
\r
104 a = ff(a, b, c, d, x[i+ 8], 7 , 0x698098D8);
\r
105 d = ff(d, a, b, c, x[i+ 9], 12, 0x8B44F7AF);
\r
106 c = ff(c, d, a, b, x[i+10], 17, 0xFFFF5BB1);
\r
107 b = ff(b, c, d, a, x[i+11], 22, 0x895CD7BE);
\r
108 a = ff(a, b, c, d, x[i+12], 7 , 0x6B901122);
\r
109 d = ff(d, a, b, c, x[i+13], 12, 0xFD987193);
\r
110 c = ff(c, d, a, b, x[i+14], 17, 0xA679438E);
\r
111 b = ff(b, c, d, a, x[i+15], 22, 0x49B40821);
\r
113 a = gg(a, b, c, d, x[i+ 1], 5 , 0xf61e2562);
\r
114 d = gg(d, a, b, c, x[i+ 6], 9 , 0xc040b340);
\r
115 c = gg(c, d, a, b, x[i+11], 14, 0x265e5a51);
\r
116 b = gg(b, c, d, a, x[i+ 0], 20, 0xe9b6c7aa);
\r
117 a = gg(a, b, c, d, x[i+ 5], 5 , 0xd62f105d);
\r
118 d = gg(d, a, b, c, x[i+10], 9 , 0x2441453);
\r
119 c = gg(c, d, a, b, x[i+15], 14, 0xd8a1e681);
\r
120 b = gg(b, c, d, a, x[i+ 4], 20, 0xe7d3fbc8);
\r
121 a = gg(a, b, c, d, x[i+ 9], 5 , 0x21e1cde6);
\r
122 d = gg(d, a, b, c, x[i+14], 9 , 0xc33707d6);
\r
123 c = gg(c, d, a, b, x[i+ 3], 14, 0xf4d50d87);
\r
124 b = gg(b, c, d, a, x[i+ 8], 20, 0x455a14ed);
\r
125 a = gg(a, b, c, d, x[i+13], 5 , 0xa9e3e905);
\r
126 d = gg(d, a, b, c, x[i+ 2], 9 , 0xfcefa3f8);
\r
127 c = gg(c, d, a, b, x[i+ 7], 14, 0x676f02d9);
\r
128 b = gg(b, c, d, a, x[i+12], 20, 0x8d2a4c8a);
\r
130 a = hh(a, b, c, d, x[i+ 5], 4 , 0xfffa3942);
\r
131 d = hh(d, a, b, c, x[i+ 8], 11, 0x8771f681);
\r
132 c = hh(c, d, a, b, x[i+11], 16, 0x6d9d6122);
\r
133 b = hh(b, c, d, a, x[i+14], 23, 0xfde5380c);
\r
134 a = hh(a, b, c, d, x[i+ 1], 4 , 0xa4beea44);
\r
135 d = hh(d, a, b, c, x[i+ 4], 11, 0x4bdecfa9);
\r
136 c = hh(c, d, a, b, x[i+ 7], 16, 0xf6bb4b60);
\r
137 b = hh(b, c, d, a, x[i+10], 23, 0xbebfbc70);
\r
138 a = hh(a, b, c, d, x[i+13], 4 , 0x289b7ec6);
\r
139 d = hh(d, a, b, c, x[i+ 0], 11, 0xeaa127fa);
\r
140 c = hh(c, d, a, b, x[i+ 3], 16, 0xd4ef3085);
\r
141 b = hh(b, c, d, a, x[i+ 6], 23, 0x4881d05);
\r
142 a = hh(a, b, c, d, x[i+ 9], 4 , 0xd9d4d039);
\r
143 d = hh(d, a, b, c, x[i+12], 11, 0xe6db99e5);
\r
144 c = hh(c, d, a, b, x[i+15], 16, 0x1fa27cf8);
\r
145 b = hh(b, c, d, a, x[i+ 2], 23, 0xc4ac5665);
\r
147 a = ii(a, b, c, d, x[i+ 0], 6 , 0xf4292244);
\r
148 d = ii(d, a, b, c, x[i+ 7], 10, 0x432aff97);
\r
149 c = ii(c, d, a, b, x[i+14], 15, 0xab9423a7);
\r
150 b = ii(b, c, d, a, x[i+ 5], 21, 0xfc93a039);
\r
151 a = ii(a, b, c, d, x[i+12], 6 , 0x655b59c3);
\r
152 d = ii(d, a, b, c, x[i+ 3], 10, 0x8f0ccc92);
\r
153 c = ii(c, d, a, b, x[i+10], 15, 0xffeff47d);
\r
154 b = ii(b, c, d, a, x[i+ 1], 21, 0x85845dd1);
\r
155 a = ii(a, b, c, d, x[i+ 8], 6 , 0x6fa87e4f);
\r
156 d = ii(d, a, b, c, x[i+15], 10, 0xfe2ce6e0);
\r
157 c = ii(c, d, a, b, x[i+ 6], 15, 0xa3014314);
\r
158 b = ii(b, c, d, a, x[i+13], 21, 0x4e0811a1);
\r
159 a = ii(a, b, c, d, x[i+ 4], 6 , 0xf7537e82);
\r
160 d = ii(d, a, b, c, x[i+11], 10, 0xbd3af235);
\r
161 c = ii(c, d, a, b, x[i+ 2], 15, 0x2ad7d2bb);
\r
162 b = ii(b, c, d, a, x[i+ 9], 21, 0xeb86d391);
\r
170 return [ a, b, c, d ];
\r
174 * Bitwise rotate a 32-bit number to the left.
\r
176 private function rol(num:uint, cnt:uint):uint
\r
178 return (num << cnt) | (num >>> (32 - cnt));
\r
182 * These functions implement the four basic operations the algorithm uses.
\r
184 private function cmn(q:uint, a:uint, b:uint, x:uint, s:uint, t:uint):uint {
\r
185 return rol(a + q + x + t, s) + b;
\r
187 private function ff(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
\r
188 return cmn((b & c) | ((~b) & d), a, b, x, s, t);
\r
190 private function gg(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
\r
191 return cmn((b & d) | (c & (~d)), a, b, x, s, t);
\r
193 private function hh(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
\r
194 return cmn(b ^ c ^ d, a, b, x, s, t);
\r
196 private function ii(a:uint, b:uint, c:uint, d:uint, x:uint, s:uint, t:uint):uint {
\r
197 return cmn(c ^ (b | (~d)), a, b, x, s, t);
\r
200 public function toString():String {
\r