2   Copyright (c) 2008, Adobe Systems Incorporated
 
   5   Redistribution and use in source and binary forms, with or without 
 
   6   modification, are permitted provided that the following conditions are
 
   9   * Redistributions of source code must retain the above copyright notice, 
 
  10     this list of conditions and the following disclaimer.
 
  12   * Redistributions in binary form must reproduce the above copyright
 
  13     notice, this list of conditions and the following disclaimer in the 
 
  14     documentation and/or other materials provided with the distribution.
 
  16   * Neither the name of Adobe Systems Incorporated nor the names of its 
 
  17     contributors may be used to endorse or promote products derived from 
 
  18     this software without specific prior written permission.
 
  20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 
  21   IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
  22   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
  23   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 
  24   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
  25   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
  26   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
  27   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
  28   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 
  29   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
  30   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
  33 package com.adobe.crypto {
 
  35         import com.adobe.utils.IntUtil;
 
  36         import flash.utils.ByteArray;   
 
  38          * The MD5 Message-Digest Algorithm
 
  40          * Implementation based on algorithm description at 
 
  41          * http://www.faqs.org/rfcs/rfc1321.html
 
  45                 public static var digest:ByteArray;
 
  47                  * Performs the MD5 hash algorithm on a string.
 
  49                  * @param s The string to hash
 
  50                  * @return A string containing the hash value of s
 
  51                  * @langversion ActionScript 3.0
 
  52                  * @playerversion Flash 8.5
 
  56                 public static function hash(s:String) :String{
 
  57                         //Convert to byteArray and send through hashBinary function
 
  58                         // so as to only have complex code in one location
 
  59                         var ba:ByteArray = new ByteArray();
 
  61                         return hashBinary(ba);
 
  64                 public static function hashBytes(s:ByteArray) :String{  
 
  69                  * Performs the MD5 hash algorithm on a ByteArray.
 
  71                  * @param s The string to hash
 
  72                  * @return A string containing the hash value of s
 
  73                  * @langversion ActionScript 3.0
 
  74                  * @playerversion Flash 8.5
 
  77                 public static function hashBinary( s:ByteArray ):String {
 
  78                         // initialize the md buffers
 
  79                         var a:int = 1732584193;
 
  80                         var b:int = -271733879;
 
  81                         var c:int = -1732584194;
 
  82                         var d:int = 271733878;
 
  84                         // variables to store previous values
 
  90                         // create the blocks from the string and
 
  91                         // save the length as a local var to reduce
 
  92                         // lookup in the loop below
 
  93                         var x:Array = createBlocks( s );
 
  94                         var len:int = x.length;
 
  96                         // loop over all of the blocks
 
  97                         for ( var i:int = 0; i < len; i += 16) {
 
  98                                 // save previous values
 
 105                                 a = ff( a, b, c, d, x[int(i+ 0)],  7, -680876936 );     // 1
 
 106                                 d = ff( d, a, b, c, x[int(i+ 1)], 12, -389564586 );     // 2
 
 107                                 c = ff( c, d, a, b, x[int(i+ 2)], 17, 606105819 );      // 3
 
 108                                 b = ff( b, c, d, a, x[int(i+ 3)], 22, -1044525330 );    // 4
 
 109                                 a = ff( a, b, c, d, x[int(i+ 4)],  7, -176418897 );     // 5
 
 110                                 d = ff( d, a, b, c, x[int(i+ 5)], 12, 1200080426 );     // 6
 
 111                                 c = ff( c, d, a, b, x[int(i+ 6)], 17, -1473231341 );    // 7
 
 112                                 b = ff( b, c, d, a, x[int(i+ 7)], 22, -45705983 );      // 8
 
 113                                 a = ff( a, b, c, d, x[int(i+ 8)],  7, 1770035416 );     // 9
 
 114                                 d = ff( d, a, b, c, x[int(i+ 9)], 12, -1958414417 );    // 10
 
 115                                 c = ff( c, d, a, b, x[int(i+10)], 17, -42063 );                 // 11
 
 116                                 b = ff( b, c, d, a, x[int(i+11)], 22, -1990404162 );    // 12
 
 117                                 a = ff( a, b, c, d, x[int(i+12)],  7, 1804603682 );     // 13
 
 118                                 d = ff( d, a, b, c, x[int(i+13)], 12, -40341101 );      // 14
 
 119                                 c = ff( c, d, a, b, x[int(i+14)], 17, -1502002290 );    // 15
 
 120                                 b = ff( b, c, d, a, x[int(i+15)], 22, 1236535329 );     // 16
 
 123                                 a = gg( a, b, c, d, x[int(i+ 1)],  5, -165796510 );     // 17
 
 124                                 d = gg( d, a, b, c, x[int(i+ 6)],  9, -1069501632 );    // 18
 
 125                                 c = gg( c, d, a, b, x[int(i+11)], 14, 643717713 );      // 19
 
 126                                 b = gg( b, c, d, a, x[int(i+ 0)], 20, -373897302 );     // 20
 
 127                                 a = gg( a, b, c, d, x[int(i+ 5)],  5, -701558691 );     // 21
 
 128                                 d = gg( d, a, b, c, x[int(i+10)],  9, 38016083 );       // 22
 
 129                                 c = gg( c, d, a, b, x[int(i+15)], 14, -660478335 );     // 23
 
 130                                 b = gg( b, c, d, a, x[int(i+ 4)], 20, -405537848 );     // 24
 
 131                                 a = gg( a, b, c, d, x[int(i+ 9)],  5, 568446438 );      // 25
 
 132                                 d = gg( d, a, b, c, x[int(i+14)],  9, -1019803690 );    // 26
 
 133                                 c = gg( c, d, a, b, x[int(i+ 3)], 14, -187363961 );     // 27
 
 134                                 b = gg( b, c, d, a, x[int(i+ 8)], 20, 1163531501 );     // 28
 
 135                                 a = gg( a, b, c, d, x[int(i+13)],  5, -1444681467 );    // 29
 
 136                                 d = gg( d, a, b, c, x[int(i+ 2)],  9, -51403784 );      // 30
 
 137                                 c = gg( c, d, a, b, x[int(i+ 7)], 14, 1735328473 );     // 31
 
 138                                 b = gg( b, c, d, a, x[int(i+12)], 20, -1926607734 );    // 32
 
 141                                 a = hh( a, b, c, d, x[int(i+ 5)],  4, -378558 );        // 33
 
 142                                 d = hh( d, a, b, c, x[int(i+ 8)], 11, -2022574463 );    // 34
 
 143                                 c = hh( c, d, a, b, x[int(i+11)], 16, 1839030562 );     // 35
 
 144                                 b = hh( b, c, d, a, x[int(i+14)], 23, -35309556 );      // 36
 
 145                                 a = hh( a, b, c, d, x[int(i+ 1)],  4, -1530992060 );    // 37
 
 146                                 d = hh( d, a, b, c, x[int(i+ 4)], 11, 1272893353 );     // 38
 
 147                                 c = hh( c, d, a, b, x[int(i+ 7)], 16, -155497632 );     // 39
 
 148                                 b = hh( b, c, d, a, x[int(i+10)], 23, -1094730640 );    // 40
 
 149                                 a = hh( a, b, c, d, x[int(i+13)],  4, 681279174 );      // 41
 
 150                                 d = hh( d, a, b, c, x[int(i+ 0)], 11, -358537222 );     // 42
 
 151                                 c = hh( c, d, a, b, x[int(i+ 3)], 16, -722521979 );     // 43
 
 152                                 b = hh( b, c, d, a, x[int(i+ 6)], 23, 76029189 );       // 44
 
 153                                 a = hh( a, b, c, d, x[int(i+ 9)],  4, -640364487 );     // 45
 
 154                                 d = hh( d, a, b, c, x[int(i+12)], 11, -421815835 );     // 46
 
 155                                 c = hh( c, d, a, b, x[int(i+15)], 16, 530742520 );      // 47
 
 156                                 b = hh( b, c, d, a, x[int(i+ 2)], 23, -995338651 );     // 48
 
 159                                 a = ii( a, b, c, d, x[int(i+ 0)],  6, -198630844 );     // 49
 
 160                                 d = ii( d, a, b, c, x[int(i+ 7)], 10, 1126891415 );     // 50
 
 161                                 c = ii( c, d, a, b, x[int(i+14)], 15, -1416354905 );    // 51
 
 162                                 b = ii( b, c, d, a, x[int(i+ 5)], 21, -57434055 );      // 52
 
 163                                 a = ii( a, b, c, d, x[int(i+12)],  6, 1700485571 );     // 53
 
 164                                 d = ii( d, a, b, c, x[int(i+ 3)], 10, -1894986606 );    // 54
 
 165                                 c = ii( c, d, a, b, x[int(i+10)], 15, -1051523 );       // 55
 
 166                                 b = ii( b, c, d, a, x[int(i+ 1)], 21, -2054922799 );    // 56
 
 167                                 a = ii( a, b, c, d, x[int(i+ 8)],  6, 1873313359 );     // 57
 
 168                                 d = ii( d, a, b, c, x[int(i+15)], 10, -30611744 );      // 58
 
 169                                 c = ii( c, d, a, b, x[int(i+ 6)], 15, -1560198380 );    // 59
 
 170                                 b = ii( b, c, d, a, x[int(i+13)], 21, 1309151649 );     // 60
 
 171                                 a = ii( a, b, c, d, x[int(i+ 4)],  6, -145523070 );     // 61
 
 172                                 d = ii( d, a, b, c, x[int(i+11)], 10, -1120210379 );    // 62
 
 173                                 c = ii( c, d, a, b, x[int(i+ 2)], 15, 718787259 );      // 63
 
 174                                 b = ii( b, c, d, a, x[int(i+ 9)], 21, -343485551 );     // 64
 
 181                         digest = new ByteArray()
 
 187                         // Finish up by concatening the buffers with their hex output
 
 188                         return IntUtil.toHex( a ) + IntUtil.toHex( b ) + IntUtil.toHex( c ) + IntUtil.toHex( d );
 
 192                  * Auxiliary function f as defined in RFC
 
 194                 private static function f( x:int, y:int, z:int ):int {
 
 195                         return ( x & y ) | ( (~x) & z );
 
 199                  * Auxiliary function g as defined in RFC
 
 201                 private static function g( x:int, y:int, z:int ):int {
 
 202                         return ( x & z ) | ( y & (~z) );
 
 206                  * Auxiliary function h as defined in RFC
 
 208                 private static function h( x:int, y:int, z:int ):int {
 
 213                  * Auxiliary function i as defined in RFC
 
 215                 private static function i( x:int, y:int, z:int ):int {
 
 216                         return y ^ ( x | (~z) );
 
 220                  * A generic transformation function.  The logic of ff, gg, hh, and
 
 221                  * ii are all the same, minus the function used, so pull that logic
 
 222                  * out and simplify the method bodies for the transoformation functions.
 
 224                 private static function transform( func:Function, a:int, b:int, c:int, d:int, x:int, s:int, t:int):int {
 
 225                         var tmp:int = a + int( func( b, c, d ) ) + x + t;
 
 226                         return IntUtil.rol( tmp, s ) +  b;
 
 230                  * ff transformation function
 
 232                 private static function ff ( a:int, b:int, c:int, d:int, x:int, s:int, t:int ):int {
 
 233                         return transform( f, a, b, c, d, x, s, t );
 
 237                  * gg transformation function
 
 239                 private static function gg ( a:int, b:int, c:int, d:int, x:int, s:int, t:int ):int {
 
 240                         return transform( g, a, b, c, d, x, s, t );
 
 244                  * hh transformation function
 
 246                 private static function hh ( a:int, b:int, c:int, d:int, x:int, s:int, t:int ):int {
 
 247                         return transform( h, a, b, c, d, x, s, t );
 
 251                  * ii transformation function
 
 253                 private static function ii ( a:int, b:int, c:int, d:int, x:int, s:int, t:int ):int {
 
 254                         return transform( i, a, b, c, d, x, s, t );
 
 258                  * Converts a string to a sequence of 16-word blocks
 
 259                  * that we'll do the processing on.  Appends padding
 
 260                  * and length in the process.
 
 262                  * @param s The string to split into blocks
 
 263                  * @return An array containing the blocks that s was
 
 266                 private static function createBlocks( s:ByteArray ):Array {
 
 267                         var blocks:Array = new Array();
 
 268                         var len:int = s.length * 8;
 
 269                         var mask:int = 0xFF; // ignore hi byte of characters > 0xFF
 
 270                         for( var i:int = 0; i < len; i += 8 ) {
 
 271                                 blocks[ int(i >> 5) ] |= ( s[ i / 8 ] & mask ) << ( i % 32 );
 
 274                         // append padding and length
 
 275                         blocks[ int(len >> 5) ] |= 0x80 << ( len % 32 );
 
 276                         blocks[ int(( ( ( len + 64 ) >>> 9 ) << 4 ) + 14) ] = len;