Community discussions

MUM Europe 2020
 
User avatar
TealFrog
just joined
Topic Author
Posts: 23
Joined: Sun Oct 02, 2011 11:56 am

Script MD5 Hash Generator

Mon Jun 18, 2012 8:54 am

A script I created to generate MD5 hashes.
# String message to MD5 Hash
# Creates a MD5 hash from a message string
# Version 1.00, 6/17/2012, Created by TealFrog
# Script tested and developed under MikroTik ROS 5.14 thru 5.17
#
# This software is identified as using and is based on the, "RSA Data Security, 
# Inc. MD5 Message-Digest Algorithm".  This program is a derived work from the RSA Data
# Security, Inc. MD5 Message-Digest Algorithm.
# See http://www.ietf.org/rfc/rfc1321.txt for further information.
#
# The author of this program makes no representations concerning either
# the merchantability of this software or the suitability of this
# software for any particular purpose or non-infringement.
# This program is provided "as is" without express or implied warranty of any kind.
# The author makes no representations or warranties of any kind as to the 
# completeness, accuracy, timeliness, availability, functionality and compliance
# with applicable laws. By using this software you accept the risk that the 
# information may be incomplete or inaccurate or may not meet your needs 
# and requirements. The author shall not be liable for any damages or 
# injury arising out of the use of this program. Use this program at your own risk. 
#
# MD5 has been shown to not be collision resistant, as such MD5 is not suitable 
# for certain applications involving security and/or cryptography, 
# see http://en.wikipedia.org/wiki/Md5 for additional information.
#
# $progName, Name of script, set appropriately
:local progName "StrToMd5"

# $arrMessages, An array containing one ore more string messages to create MD5 hash from 
:local arrMessages ( "ABCDEFGHIJKLMNOPQRSTUVWZYZ",   \
                     "abcedefghijklmnopqrstuvwxyz",  \
                     "The quick brown fox jumps over the lazy dog." )

# $strPrefix, Set to a prefix to add before MD5 hash, set "" for empty
:local strPrefix "0x"

# $strSuffix, Set to a suffix to add after MD5 hash, set "" for empty
:local strSuffix ""

# Set $Debug to 1 for additional output, set to zero to turn off debug
:local Debug 0

# $strHexValues, Used to create hexadecimal output
:local strHexValues "0123456789abcdef"
# To have uppercase hexadecimal A-F use the next line instead of the above
# :local strHexValues "0123456789ABCDEF"

# No futher modification required beyond this point unless customizing script
# Start by defining constant values

# ASCII Table $CharSet[0..127]
:local arrCharSet ( "\00", "\01", "\02", "\03", "\04", "\05", "\06", "\07", \ 
                    "\08", "\09", "\0A", "\0B", "\0C", "\0D", "\0E", "\0F", \ 
                    "\10", "\11", "\12", "\13", "\14", "\15", "\16", "\17", \
                    "\18", "\19", "\1A", "\1B", "\1C", "\1D", "\1E", "\1F", \
                    "\20", "\21", "\22", "\23", "\24", "\25", "\26", "\27", \
                    "\28", "\29", "\2A", "\2B", "\2C", "\2D", "\2E", "\2F", \
                    "\30", "\31", "\32", "\33", "\34", "\35", "\36", "\37", \
                    "\38", "\39", "\3A", "\3B", "\3C", "\3D", "\3E", "\3F", \
                    "\40", "\41", "\42", "\43", "\44", "\45", "\46", "\47", \ 
                    "\48", "\49", "\4A", "\4B", "\4C", "\4D", "\4E", "\4F", \
                    "\50", "\51", "\52", "\53", "\54", "\55", "\56", "\57", \
                    "\58", "\59", "\5A", "\5B", "\5C", "\5D", "\5E", "\5F", \
                    "\60", "\61", "\62", "\63", "\64", "\65", "\66", "\67", \
                    "\68", "\69", "\6A", "\6B", "\6C", "\6D", "\6E", "\6F", \
                    "\70", "\71", "\72", "\73", "\74", "\75", "\76", "\77", \
                    "\78", "\79", "\7A", "\7B", "\7C", "\7D", "\7E", "\7F" ) 

# k[i] = floor(abs(sin(i + 1)) × 4294967296) 
# Or just use the following table $k[0..63]:
:local k ( 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, \
           0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, \
           0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, \
           0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821, \
           0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, \
           0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, \
           0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, \
           0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A, \
           0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, \
           0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70, \
           0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, \
           0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665, \
           0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, \
           0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1, \
           0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1, \
           0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391 )

:local a 0x67452301 
:local b 0xEFCDAB89
:local c 0x98BADCFE
:local d 0x10325476

:local AA 0x67452301
:local BB 0xEFCDAB89
:local CC 0x98BADCFE
:local DD 0x10325476

:local s1 (  7, 12, 17, 22 )
:local s2 (  5,  9, 14, 20 )
:local s3 (  4, 11, 16, 23 )
:local s4 (  6, 10, 15, 21 )

:local i 0
:local j 0
:local x 0
:local S 0
:local T 0
:local lcv 0
:local tmp1 0

:local arrMd5State {}
:local arrWordArray {}
:local ch ""
:local iByteCount 0
:local iCharVal 3
:local iDec 0
:local iHexDigit 8
:local iMd5State 0
:local lBytePosition 0
:local lMessageLength 0
:local lNumberOfWords 0        
:local lShiftedVal 0
:local lWordArray {}
:local lWordArrLen 0
:local lWordCount 0
:local sHex ""
:local sMd5Hash ""
:local sMd5Output ""
:local strWordArray ""

# Start of main program and message loop
:put "$progName: Running..."
:foreach strMessage in=[ :toarray $arrMessages ] do={
   :put "$progName: Message: $strMessage"
   :set ch ""
   :set lShiftedVal 0
   :set lWordCount 0
   :set iByteCount 0
   :set iCharVal 3
   :set lBytePosition 0
   :set lMessageLength [ :len $strMessage ]
   :set lNumberOfWords ( ( ( ( $lMessageLength + 8 ) / 64 ) + 1 ) * 16 )        
   :set strWordArray ""
   :set arrWordArray {}

# Convert to word array 
   :for i from=1 to=($lNumberOfWords) do={
      :set strWordArray ("0," . $strWordArray)
   }
   :set strWordArray  [ :pick $strWordArray 0 ( [ :len $strWordArray ] - 1 ) ]
   :set arrWordArray [ :toarray $strWordArray ]
   
   :if ( $Debug > 0 ) do={
      :put ("$progName: Message Length: " . $lMessageLength)
      :put ("$progName: Number of Words: " . $lNumberOfWords)
   }
   :while ($iByteCount < $lMessageLength) do={
      :set lWordCount ($iByteCount / 4)
      :set lBytePosition (($iByteCount % 4) * 8)
         :if (($lBytePosition < 0) or ($lBytePosition > 31)) do={
            :error ( "$progName: Error --  Calculating byte position " . \
			       "# $lBytePosition, must be 0 thru 31." )
         }
         :set ch [ :pick $strMessage $iByteCount ]
         :if ( [ :len [ :find $arrCharSet $ch ] ] > 0 ) do={
            :set iCharVal ([ :tonum [ :find $arrCharSet $ch ] ])
         } else={
            :error "$progName: Error -- Input contains undefined ASCII value."
         }
         :if ( $Debug > 0 ) do={
            :put ( "$progName: parsed character \$ch: '$ch' " . \
			     "ASCII value \$iCharVal: $iCharVal" )
         }
         :set lShiftedVal ((($iCharVal) << ($lBytePosition)) | \
		                   (($iCharVal) >> (32-($lBytePosition))))
         :if ($iByteCount = 0) do={
            :set lShiftedVal (([ :tonum $lShiftedVal ] + 0) & 0xFFFFFFFF)
            :set arrWordArray (([ :tonum $lShiftedVal ]), \
			                    [ :pick $arrWordArray 1 [ :len $arrWordArray] ])
         } else={
            :set lShiftedVal (([ :tonum [ :pick $arrWordArray $lWordCount] ] + 0) | \
			                  ([ :tonum $lShiftedVal ] + 0))
            :set lShiftedVal (([ :tonum $lShiftedVal ] + 0) & 0xFFFFFFFF)
            :set arrWordArray  ([ :pick $arrWordArray 0 $lWordCount ], $lShiftedVal, \
               [ :pick $arrWordArray ([ :tonum $lWordCount ] + 1) [ :len $arrWordArray] ])   
         }
         :set iByteCount ( $iByteCount + 1 )
      }
      :set lWordCount ( $iByteCount / 4 )
      :set lBytePosition ( ( $iByteCount % 4 ) * 8 )
      :set lShiftedVal [ :pick $arrWordArray $lWordCount ]
      
      :set lShiftedVal ( ( [ :tonum [ :pick $arrWordArray $lWordCount ] ] + 0 ) | \
                         ( ( 0x80 << $lBytePosition ) | \
				           ( 0x80 >> ( 32 - $lBytePosition ) ) ) ) 
      
      :set arrWordArray  ( ( [ :pick $arrWordArray 0 $lWordCount ]  ),  \
                             [ :tonum $lShiftedVal ], \
                           ( [ :pick $arrWordArray ( [ :tonum $lWordCount ] + 1 ) \
   					    [ :len $arrWordArray ] ] ) ) 
					       
      :set arrWordArray  [ :toarray ( ( [ :pick $arrWordArray 0 ($lNumberOfWords - 2) ] ), \
                                    ( ( ( [ :tonum $lMessageLength ] + 0 ) << 3 ) | \
   							     ( ( [ :tonum $lMessageLength ] + 0 ) >> 29 ) ), \
							        ( ( [ :tonum $lMessageLength ] + 0 )  >> 29 ) ) ]
      :set lWordArray [ :toarray $arrWordArray ]
      :set lWordArrLen ( ( [ :len $lWordArray ] ) - 1 )

### Main Loop ###
      :set tmp1 0
      :set x 0
      :set T 0
      :set S 0
      :set i 0
      :set j 0
      :for lcv from=0 to=( $lWordArrLen ) step=16 do={
         :set a 0x67452301 
         :set b 0xEFCDAB89
         :set c 0x98BADCFE
         :set d 0x10325476
         :set AA [ :tonum $a ]
         :set BB [ :tonum $b ]
         :set CC [ :tonum $c ]
         :set DD [ :tonum $d ]

### Round 1 ### 
         :for i from=0 to=15 do={
            :set x ( [ :tonum [ :pick $lWordArray ( $i & 15 ) ] ] + 0 )
            :set T ( [ :tonum [ :pick $k $i ] ] + 0 )
            :set S ( [ :tonum [ :pick $s1 ( $i & 3 ) ] ] + 0 )
# Next line is an alternate mmethod, instead of the line after it	  
#         :set tmp1 ( ( (($b & $c) | (((($b + 1) * -1)) & $d)) + $a + $T + $x ) & 0xFFFFFFFF )
            :set tmp1 ( ( ( $d ^ ( $b & ( $c ^ $d ) ) ) + $a + $T + $x ) & 0xFFFFFFFF )
            :set tmp1 (((tmp1 << $S ) | (($tmp1 >> (32 - $S)))) & 0xFFFFFFFF)
            :set tmp1 ( ( $tmp1 + $b ) & 0xFFFFFFFF )
            :if ( $Debug > 0 ) do={			
               :put ("$progName: Round 1, Answer \$tmp1: $tmp1") 
            }			   
# Rotate a,b,c,d params positions, e.g. d, a, b, c ... c, d, a, b ... b, c, d, a 
# and a gets new value from tmp1
            :set a ( ( [ :tonum $d ] + 0 ) & 0xFFFFFFFF )
            :set d ( ( [ :tonum $c ] + 0 ) & 0xFFFFFFFF )
            :set c ( ( [ :tonum $b ] + 0 ) & 0xFFFFFFFF )
            :set b ( ( [ :tonum $tmp1 ] + 0 ) & 0xFFFFFFFF )
         }
      
### Round 2 ###
         :set j 1
         :for i from=0 to=15 do={
            :set x ( [ :tonum [ :pick $lWordArray ( ( [ :tonum $j ] + 0 ) & 15 ) ] ] + 0 )
            :set T ( [ :tonum [ :pick $k ( $i + 16 ) ] ] + 0 )
            :set S ( [ :tonum [ :pick $s2 ( $i & 3 ) ] ] + 0 )
            :set tmp1 ( ( ( $c ^ ( $d & ( $b ^ $c ) ) ) + $a + $T + $x ) & 0xFFFFFFFF )
            :set tmp1 (((tmp1 << $S ) | (($tmp1 >> (32 - $S)))) & 0xFFFFFFFF)
            :set tmp1 ( ( $tmp1 + $b ) & 0xFFFFFFFF )
            :if ( $Debug > 0 ) do={			
               :put ("$progName: Round 2, Answer \$tmp1: $tmp1") 
            }			   
# Rotate a,b,c,d param positions, e.g. d, a, b, c ... c, d, a, b ... b, c, d, a
            :set a ( ( [ :tonum $d ] + 0 ) & 0xFFFFFFFF )
            :set d ( ( [ :tonum $c ] + 0 ) & 0xFFFFFFFF )
            :set c ( ( [ :tonum $b ] + 0 ) & 0xFFFFFFFF )
            :set b ( ( [ :tonum $tmp1 ] + 0 ) & 0xFFFFFFFF )
            :set j ( $j + 5 )
         }
         
### Round 3 ###
         :set j 5
         :for i from=0 to=15 do={
            :set x ( [ :tonum [ :pick $lWordArray ( ( [ :tonum $j ] + 0 ) & 15 ) ] ] + 0 )
            :set T ( [ :tonum [ :pick $k ( $i + 32 ) ] ] + 0 )
            :set S ( [ :tonum [ :pick $s3 ( $i & 3 ) ] ] + 0 )
            :set tmp1 ( ( ( $b ^ $c ^ $d ) + $a + $T + $x ) & 0xFFFFFFFF )
            :set tmp1 (((tmp1 << $S ) | (($tmp1 >> (32 - $S)))) & 0xFFFFFFFF)
            :set tmp1 ( ( $tmp1 + $b ) & 0xFFFFFFFF )
            :if ( $Debug > 0 ) do={			
               :put ("$progName: Round 3, Answer \$tmp1: $tmp1") 
            }			   
# Rotate a,b,c,d param positions, e.g. d, a, b, c ... c, d, a, b ... b, c, d, a
            :set a ( ( [ :tonum $d ] + 0) & 0xFFFFFFFF )
            :set d ( ( [ :tonum $c ] + 0) & 0xFFFFFFFF )
            :set c ( ( [ :tonum $b ] + 0) & 0xFFFFFFFF )
            :set b ( ( [ :tonum $tmp1 ] + 0) & 0xFFFFFFFF )
            :set j ( $j + 3 )
         }
         
### Round 4 ###
         :set j 0
         :for i from=0 to=15 do={
            :set x ( [ :tonum [ :pick $lWordArray ( ( [ :tonum $j ] + 0 ) & 15 ) ] ] + 0 )
            :set T ( [ :tonum [ :pick $k ( $i + 48 ) ] ] + 0 )
            :set S ( [ :tonum [ :pick $s4 ( $i & 3 ) ] ] + 0 )
# Next line is alternate method to the line following	  
#         :set tmp1 ( $c ^ ( $b | ( ( $d & 0xFFFFFFFF ) ^ 0xFFFFFFFF ) ) )
            :set tmp1 ( ( $c ^ ( $b | ( -1 * ( $d + 1 ) ) ) ) & 0xFFFFFFFF )
            :set tmp1 ( ( $tmp1 + $a + $T + $x ) & 0xFFFFFFFF )
            :set tmp1 ( ((tmp1 << $S ) | (($tmp1 >> (32 - $S)))) & 0xFFFFFFFF )
            :set tmp1 ( ( $tmp1 + $b ) & 0xFFFFFFFF )
            :if ( $Debug > 0 ) do={			
               :put ("$progName: Round 4, Answer \$tmp1: $tmp1") 
            }			   
# Rotate a,b,c,d param positions, e.g. d, a, b, c ... c, d, a, b ... b, c, d, a
            :set a ( ( [ :tonum $d ] + 0) & 0xFFFFFFFF )
            :set d ( ( [ :tonum $c ] + 0) & 0xFFFFFFFF )
            :set c ( ( [ :tonum $b ] + 0) & 0xFFFFFFFF )
            :set b ( ( [ :tonum $tmp1 ] + 0) & 0xFFFFFFFF )
            :set j ( $j + 7 )
         }      
         :set a ( ( $a + $AA ) & 0xFFFFFFFF )    
         :set b ( ( $b + $BB ) & 0xFFFFFFFF )    
         :set c ( ( $c + $CC ) & 0xFFFFFFFF )    
         :set d ( ( $d + $DD ) & 0xFFFFFFFF )    
      }
      :set arrMd5State [ :toarray "$a, $b, $c, $d" ]
      :set sMd5Hash ""
      :set sMd5Output ""
      :set iDec 0
      :set iMd5State 0
      :set sHex ""
      :for i from=0 to=3 do={
         :set iMd5State [ :pick $arrMd5State $i ] 	  
         :for j from=0 to=3 do={
	        :set iMd5State ( [ :tonum $iMd5State ] & 0xFFFFFFFF )
            :if ( $j < 1 ) do={
               :set iDec ( [ :tonum $iMd5State ] & 255 )
            } else={
		       :set iDec ( ( $iMd5State & 0x7FFFFFFE ) / ( 2 << ( ( $j * 8 ) - 1 ) ) )
   		    :if ( ( $iMd5State & 0x80000000 ) > 0 ) do={
	              :set iDec ( $iDec | ( 0x40000000 /  ( 2 << ( ( $j * 8 ) - 2 ) ) ) )
 	           }
   		       :set iDec ( $iDec & 0xFF ) 
            }
   	        :set sHex ""
            :for k from=0 to=( 4 * ( $iHexDigit - 1 ) ) step=4 do={
               :set sHex ( [ :pick [ :tostr $strHexValues ] \
			             ( ( $iDec >> $k ) & 0xF ) \ 
						 ( ( ( $iDec >> $k ) & 0xF ) + 1 ) ] . $sHex ) 
            }
   	        :set sHex [ :tostr $sHex ]
	        :set sHex [ :pick $sHex ( [ :len $sHex ] - 2 ) [ :len $sHex ] ]
            :set sMd5Output ( $sMd5Output . $sHex )	  
         }
   }
# Modify next line to customize MD5 output string	  
   :put ( [ :tostr $strPrefix ] . [ :tostr $sMd5Output ] . [ :tostr $strSuffix ] )
}
:put "$progName: Done."
TealFrog
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2411
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Script MD5 Hash Generator

Mon Jun 18, 2012 1:15 pm

One silly question if I may... why? Is there at least one use case for this?
PEAR2_Net_RouterOS(1.0.0b6) - My API client in PHP
(Rate my posts? If you want... no pressure...)
 
User avatar
TealFrog
just joined
Topic Author
Posts: 23
Joined: Sun Oct 02, 2011 11:56 am

Re: Script MD5 Hash Generator

Tue Jun 19, 2012 2:13 am

Admittedly, the script by itself "as-is", is almost useless. It is really meant to fill a niche and be used as a solution to be incorporated into other scripts with the MD5 hash acting as either input to or output from another program or script.

For those who are unaware, MD5, as well as other hashes, can be used to check integrity, create signatures and/or for authentication purposes. Specifically, hashes, i.e. MD5, can be used to check file integrity and/or to create/store a salted password/passphrase. As noted in the scripts comments, MD5 has been determined to be insecure, so if given a choice I would use a different hash algorithm for security purposes. Nonetheless MD5 has been used widely and if given a choice between storing a password in the clear or storing a salted and hashed password using MD5, I'd pick the latter.

Originally, I had a need for MD5 under MikroTik with the intent to check file integrity, to specifically determine whether a particular file had changed. When searching the forums other people were also looking for an MD5 script for other purposes. Someone on the forums was (and still may be) offering an MD5 script, for a small fee. I wanted a free solution, so I started to write my own MD5 script.

Ultimately, I ended up not using MD5 for my solution and I shelved the MD5 script. The MD5 script sat for a period of months at about 95% completed. It bothered me that I hadn't finished the MD5 script, so having a little time and revisiting the script I finished it and posted it here. If I had used the script as I had initially intended, the script would actually have one use case. Since at one time there was an expressed interest on the forums, http://forum.mikrotik.com/viewtopic.php ... 3&p=208825, I assume that there was or is an actual need for such a script and that there are actual cases of a similar script being in use.

Regards,
TealFrog
 
paris9
newbie
Posts: 32
Joined: Mon Feb 03, 2014 9:31 am

Re: Script MD5 Hash Generator

Sun Mar 30, 2014 12:47 am

I have been trying out your script and was wondering if you could help me with a problem. I have been unable to get a match with php's md5 for messages lengths over 55 chars. If you could provide any insight as to why this might be it would be greatly appreciated. I have included two debug logs, one with a message length of 55 chars and the second with 56 chars. The one with 56 chars fails to match with php's md5. Thanks much!


DEBUG OUTPUT FOR 55 CHARS


StrToMd5: Message: 0123456789012345678901234567890123456789012345678901234
StrToMd5: Message Length: 55
StrToMd5: Number of Words: 16
StrToMd5: parsed character $ch: '0' ASCII value $iCharVal: 48
StrToMd5: parsed character $ch: '1' ASCII value $iCharVal: 49
StrToMd5: parsed character $ch: '2' ASCII value $iCharVal: 50
StrToMd5: parsed character $ch: '3' ASCII value $iCharVal: 51
StrToMd5: parsed character $ch: '4' ASCII value $iCharVal: 52
StrToMd5: parsed character $ch: '5' ASCII value $iCharVal: 53
StrToMd5: parsed character $ch: '6' ASCII value $iCharVal: 54
StrToMd5: parsed character $ch: '7' ASCII value $iCharVal: 55
StrToMd5: parsed character $ch: '8' ASCII value $iCharVal: 56
StrToMd5: parsed character $ch: '9' ASCII value $iCharVal: 57
StrToMd5: parsed character $ch: '0' ASCII value $iCharVal: 48
StrToMd5: parsed character $ch: '1' ASCII value $iCharVal: 49
StrToMd5: parsed character $ch: '2' ASCII value $iCharVal: 50
StrToMd5: parsed character $ch: '3' ASCII value $iCharVal: 51
StrToMd5: parsed character $ch: '4' ASCII value $iCharVal: 52
StrToMd5: parsed character $ch: '5' ASCII value $iCharVal: 53
StrToMd5: parsed character $ch: '6' ASCII value $iCharVal: 54
StrToMd5: parsed character $ch: '7' ASCII value $iCharVal: 55
StrToMd5: parsed character $ch: '8' ASCII value $iCharVal: 56
StrToMd5: parsed character $ch: '9' ASCII value $iCharVal: 57
StrToMd5: parsed character $ch: '0' ASCII value $iCharVal: 48
StrToMd5: parsed character $ch: '1' ASCII value $iCharVal: 49
StrToMd5: parsed character $ch: '2' ASCII value $iCharVal: 50
StrToMd5: parsed character $ch: '3' ASCII value $iCharVal: 51
StrToMd5: parsed character $ch: '4' ASCII value $iCharVal: 52
StrToMd5: parsed character $ch: '5' ASCII value $iCharVal: 53
StrToMd5: parsed character $ch: '6' ASCII value $iCharVal: 54
StrToMd5: parsed character $ch: '7' ASCII value $iCharVal: 55
StrToMd5: parsed character $ch: '8' ASCII value $iCharVal: 56
StrToMd5: parsed character $ch: '9' ASCII value $iCharVal: 57
StrToMd5: parsed character $ch: '0' ASCII value $iCharVal: 48
StrToMd5: parsed character $ch: '1' ASCII value $iCharVal: 49
StrToMd5: parsed character $ch: '2' ASCII value $iCharVal: 50
StrToMd5: parsed character $ch: '3' ASCII value $iCharVal: 51
StrToMd5: parsed character $ch: '4' ASCII value $iCharVal: 52
StrToMd5: parsed character $ch: '5' ASCII value $iCharVal: 53
StrToMd5: parsed character $ch: '6' ASCII value $iCharVal: 54
StrToMd5: parsed character $ch: '7' ASCII value $iCharVal: 55
StrToMd5: parsed character $ch: '8' ASCII value $iCharVal: 56
StrToMd5: parsed character $ch: '9' ASCII value $iCharVal: 57
StrToMd5: parsed character $ch: '0' ASCII value $iCharVal: 48
StrToMd5: parsed character $ch: '1' ASCII value $iCharVal: 49
StrToMd5: parsed character $ch: '2' ASCII value $iCharVal: 50
StrToMd5: parsed character $ch: '3' ASCII value $iCharVal: 51
StrToMd5: parsed character $ch: '4' ASCII value $iCharVal: 52
StrToMd5: parsed character $ch: '5' ASCII value $iCharVal: 53
StrToMd5: parsed character $ch: '6' ASCII value $iCharVal: 54
StrToMd5: parsed character $ch: '7' ASCII value $iCharVal: 55
StrToMd5: parsed character $ch: '8' ASCII value $iCharVal: 56
StrToMd5: parsed character $ch: '9' ASCII value $iCharVal: 57
StrToMd5: parsed character $ch: '0' ASCII value $iCharVal: 48
StrToMd5: parsed character $ch: '1' ASCII value $iCharVal: 49
StrToMd5: parsed character $ch: '2' ASCII value $iCharVal: 50
StrToMd5: parsed character $ch: '3' ASCII value $iCharVal: 51
StrToMd5: parsed character $ch: '4' ASCII value $iCharVal: 52
StrToMd5: Round 1, Answer $tmp1: 1043889934
StrToMd5: Round 1, Answer $tmp1: 3976727801
StrToMd5: Round 1, Answer $tmp1: 1496991403
StrToMd5: Round 1, Answer $tmp1: 785365157
StrToMd5: Round 1, Answer $tmp1: 708128447
StrToMd5: Round 1, Answer $tmp1: 1090829548
StrToMd5: Round 1, Answer $tmp1: 507743179
StrToMd5: Round 1, Answer $tmp1: 350415511
StrToMd5: Round 1, Answer $tmp1: 758105254
StrToMd5: Round 1, Answer $tmp1: 2024392292
StrToMd5: Round 1, Answer $tmp1: 2205205030
StrToMd5: Round 1, Answer $tmp1: 246492053
StrToMd5: Round 1, Answer $tmp1: 589028787
StrToMd5: Round 1, Answer $tmp1: 2592589121
StrToMd5: Round 1, Answer $tmp1: 2290754940
StrToMd5: Round 1, Answer $tmp1: 3872072640
StrToMd5: Round 2, Answer $tmp1: 1177967738
StrToMd5: Round 2, Answer $tmp1: 3382687850
StrToMd5: Round 2, Answer $tmp1: 1442751009
StrToMd5: Round 2, Answer $tmp1: 564902236
StrToMd5: Round 2, Answer $tmp1: 3524707176
StrToMd5: Round 2, Answer $tmp1: 759797318
StrToMd5: Round 2, Answer $tmp1: 3289063093
StrToMd5: Round 2, Answer $tmp1: 3960348389
StrToMd5: Round 2, Answer $tmp1: 325783048
StrToMd5: Round 2, Answer $tmp1: 851916345
StrToMd5: Round 2, Answer $tmp1: 271384215
StrToMd5: Round 2, Answer $tmp1: 1669755681
StrToMd5: Round 2, Answer $tmp1: 1774915565
StrToMd5: Round 2, Answer $tmp1: 1276194165
StrToMd5: Round 2, Answer $tmp1: 2788600250
StrToMd5: Round 2, Answer $tmp1: 3488286956
StrToMd5: Round 3, Answer $tmp1: 4230705432
StrToMd5: Round 3, Answer $tmp1: 1835476493
StrToMd5: Round 3, Answer $tmp1: 225497022
StrToMd5: Round 3, Answer $tmp1: 3139819051
StrToMd5: Round 3, Answer $tmp1: 4031961270
StrToMd5: Round 3, Answer $tmp1: 532894330
StrToMd5: Round 3, Answer $tmp1: 3506494602
StrToMd5: Round 3, Answer $tmp1: 3656823063
StrToMd5: Round 3, Answer $tmp1: 3748878962
StrToMd5: Round 3, Answer $tmp1: 3197104922
StrToMd5: Round 3, Answer $tmp1: 391153224
StrToMd5: Round 3, Answer $tmp1: 1335277281
StrToMd5: Round 3, Answer $tmp1: 3694727214
StrToMd5: Round 3, Answer $tmp1: 3010396938
StrToMd5: Round 3, Answer $tmp1: 1551129277
StrToMd5: Round 3, Answer $tmp1: 1748018565
StrToMd5: Round 4, Answer $tmp1: 2121490450
StrToMd5: Round 4, Answer $tmp1: 3563463440
StrToMd5: Round 4, Answer $tmp1: 573078498
StrToMd5: Round 4, Answer $tmp1: 2680845324
StrToMd5: Round 4, Answer $tmp1: 1550383800
StrToMd5: Round 4, Answer $tmp1: 3474919971
StrToMd5: Round 4, Answer $tmp1: 3498841716
StrToMd5: Round 4, Answer $tmp1: 1564423957
StrToMd5: Round 4, Answer $tmp1: 195342272
StrToMd5: Round 4, Answer $tmp1: 1592538304
StrToMd5: Round 4, Answer $tmp1: 1340048581
StrToMd5: Round 4, Answer $tmp1: 3570997936
StrToMd5: Round 4, Answer $tmp1: 1644844909
StrToMd5: Round 4, Answer $tmp1: 2769434966
StrToMd5: Round 4, Answer $tmp1: 3263657448
StrToMd5: Round 4, Answer $tmp1: 116786597
6e7a4fc92eb1c3f6e652425bcc8d44b5
PHP MD5: 6e7a4fc92eb1c3f6e652425bcc8d44b5


DEBUG OUTPUT FOR 56 CHARS


StrToMd5: Message: 01234567890123456789012345678901234567890123456789012345
StrToMd5: Message Length: 56
StrToMd5: Number of Words: 32
StrToMd5: parsed character $ch: '0' ASCII value $iCharVal: 48
StrToMd5: parsed character $ch: '1' ASCII value $iCharVal: 49
StrToMd5: parsed character $ch: '2' ASCII value $iCharVal: 50
StrToMd5: parsed character $ch: '3' ASCII value $iCharVal: 51
StrToMd5: parsed character $ch: '4' ASCII value $iCharVal: 52
StrToMd5: parsed character $ch: '5' ASCII value $iCharVal: 53
StrToMd5: parsed character $ch: '6' ASCII value $iCharVal: 54
StrToMd5: parsed character $ch: '7' ASCII value $iCharVal: 55
StrToMd5: parsed character $ch: '8' ASCII value $iCharVal: 56
StrToMd5: parsed character $ch: '9' ASCII value $iCharVal: 57
StrToMd5: parsed character $ch: '0' ASCII value $iCharVal: 48
StrToMd5: parsed character $ch: '1' ASCII value $iCharVal: 49
StrToMd5: parsed character $ch: '2' ASCII value $iCharVal: 50
StrToMd5: parsed character $ch: '3' ASCII value $iCharVal: 51
StrToMd5: parsed character $ch: '4' ASCII value $iCharVal: 52
StrToMd5: parsed character $ch: '5' ASCII value $iCharVal: 53
StrToMd5: parsed character $ch: '6' ASCII value $iCharVal: 54
StrToMd5: parsed character $ch: '7' ASCII value $iCharVal: 55
StrToMd5: parsed character $ch: '8' ASCII value $iCharVal: 56
StrToMd5: parsed character $ch: '9' ASCII value $iCharVal: 57
StrToMd5: parsed character $ch: '0' ASCII value $iCharVal: 48
StrToMd5: parsed character $ch: '1' ASCII value $iCharVal: 49
StrToMd5: parsed character $ch: '2' ASCII value $iCharVal: 50
StrToMd5: parsed character $ch: '3' ASCII value $iCharVal: 51
StrToMd5: parsed character $ch: '4' ASCII value $iCharVal: 52
StrToMd5: parsed character $ch: '5' ASCII value $iCharVal: 53
StrToMd5: parsed character $ch: '6' ASCII value $iCharVal: 54
StrToMd5: parsed character $ch: '7' ASCII value $iCharVal: 55
StrToMd5: parsed character $ch: '8' ASCII value $iCharVal: 56
StrToMd5: parsed character $ch: '9' ASCII value $iCharVal: 57
StrToMd5: parsed character $ch: '0' ASCII value $iCharVal: 48
StrToMd5: parsed character $ch: '1' ASCII value $iCharVal: 49
StrToMd5: parsed character $ch: '2' ASCII value $iCharVal: 50
StrToMd5: parsed character $ch: '3' ASCII value $iCharVal: 51
StrToMd5: parsed character $ch: '4' ASCII value $iCharVal: 52
StrToMd5: parsed character $ch: '5' ASCII value $iCharVal: 53
StrToMd5: parsed character $ch: '6' ASCII value $iCharVal: 54
StrToMd5: parsed character $ch: '7' ASCII value $iCharVal: 55
StrToMd5: parsed character $ch: '8' ASCII value $iCharVal: 56
StrToMd5: parsed character $ch: '9' ASCII value $iCharVal: 57
StrToMd5: parsed character $ch: '0' ASCII value $iCharVal: 48
StrToMd5: parsed character $ch: '1' ASCII value $iCharVal: 49
StrToMd5: parsed character $ch: '2' ASCII value $iCharVal: 50
StrToMd5: parsed character $ch: '3' ASCII value $iCharVal: 51
StrToMd5: parsed character $ch: '4' ASCII value $iCharVal: 52
StrToMd5: parsed character $ch: '5' ASCII value $iCharVal: 53
StrToMd5: parsed character $ch: '6' ASCII value $iCharVal: 54
StrToMd5: parsed character $ch: '7' ASCII value $iCharVal: 55
StrToMd5: parsed character $ch: '8' ASCII value $iCharVal: 56
StrToMd5: parsed character $ch: '9' ASCII value $iCharVal: 57
StrToMd5: parsed character $ch: '0' ASCII value $iCharVal: 48
StrToMd5: parsed character $ch: '1' ASCII value $iCharVal: 49
StrToMd5: parsed character $ch: '2' ASCII value $iCharVal: 50
StrToMd5: parsed character $ch: '3' ASCII value $iCharVal: 51
StrToMd5: parsed character $ch: '4' ASCII value $iCharVal: 52
StrToMd5: parsed character $ch: '5' ASCII value $iCharVal: 53
StrToMd5: Round 1, Answer $tmp1: 1043889934
StrToMd5: Round 1, Answer $tmp1: 3976727801
StrToMd5: Round 1, Answer $tmp1: 1496991403
StrToMd5: Round 1, Answer $tmp1: 785365157
StrToMd5: Round 1, Answer $tmp1: 708128447
StrToMd5: Round 1, Answer $tmp1: 1090829548
StrToMd5: Round 1, Answer $tmp1: 507743179
StrToMd5: Round 1, Answer $tmp1: 350415511
StrToMd5: Round 1, Answer $tmp1: 758105254
StrToMd5: Round 1, Answer $tmp1: 2024392292
StrToMd5: Round 1, Answer $tmp1: 2205205030
StrToMd5: Round 1, Answer $tmp1: 246492053
StrToMd5: Round 1, Answer $tmp1: 589028787
StrToMd5: Round 1, Answer $tmp1: 2592587921
StrToMd5: Round 1, Answer $tmp1: 2115641548
StrToMd5: Round 1, Answer $tmp1: 3631676176
StrToMd5: Round 2, Answer $tmp1: 1784287161
StrToMd5: Round 2, Answer $tmp1: 1701006001
StrToMd5: Round 2, Answer $tmp1: 2770721335
StrToMd5: Round 2, Answer $tmp1: 2262270538
StrToMd5: Round 2, Answer $tmp1: 2268326889
StrToMd5: Round 2, Answer $tmp1: 568927790
StrToMd5: Round 2, Answer $tmp1: 1828849176
StrToMd5: Round 2, Answer $tmp1: 577691891
StrToMd5: Round 2, Answer $tmp1: 4184934364
StrToMd5: Round 2, Answer $tmp1: 328992381
StrToMd5: Round 2, Answer $tmp1: 657433351
StrToMd5: Round 2, Answer $tmp1: 3937119657
StrToMd5: Round 2, Answer $tmp1: 3510949256
StrToMd5: Round 2, Answer $tmp1: 1378320286
StrToMd5: Round 2, Answer $tmp1: 3914302571
StrToMd5: Round 2, Answer $tmp1: 31869769
StrToMd5: Round 3, Answer $tmp1: 4058338996
StrToMd5: Round 3, Answer $tmp1: 3288109044
StrToMd5: Round 3, Answer $tmp1: 1892110870
StrToMd5: Round 3, Answer $tmp1: 107521821
StrToMd5: Round 3, Answer $tmp1: 961001941
StrToMd5: Round 3, Answer $tmp1: 409290396
StrToMd5: Round 3, Answer $tmp1: 1197999769
StrToMd5: Round 3, Answer $tmp1: 2383894880
StrToMd5: Round 3, Answer $tmp1: 288337030
StrToMd5: Round 3, Answer $tmp1: 1573508346
StrToMd5: Round 3, Answer $tmp1: 3912624502
StrToMd5: Round 3, Answer $tmp1: 988659220
StrToMd5: Round 3, Answer $tmp1: 1607546607
StrToMd5: Round 3, Answer $tmp1: 1478383357
StrToMd5: Round 3, Answer $tmp1: 2626854136
StrToMd5: Round 3, Answer $tmp1: 3933778205
StrToMd5: Round 4, Answer $tmp1: 2422522843
StrToMd5: Round 4, Answer $tmp1: 3421437809
StrToMd5: Round 4, Answer $tmp1: 3398617929
StrToMd5: Round 4, Answer $tmp1: 517644729
StrToMd5: Round 4, Answer $tmp1: 3981120703
StrToMd5: Round 4, Answer $tmp1: 2208039566
StrToMd5: Round 4, Answer $tmp1: 558860515
StrToMd5: Round 4, Answer $tmp1: 3871410182
StrToMd5: Round 4, Answer $tmp1: 1540357410
StrToMd5: Round 4, Answer $tmp1: 2069010446
StrToMd5: Round 4, Answer $tmp1: 2102830634
StrToMd5: Round 4, Answer $tmp1: 4139035227
StrToMd5: Round 4, Answer $tmp1: 141808929
StrToMd5: Round 4, Answer $tmp1: 1431334097
StrToMd5: Round 4, Answer $tmp1: 46728212
StrToMd5: Round 4, Answer $tmp1: 3909142066
StrToMd5: Round 1, Answer $tmp1: 1043889934
StrToMd5: Round 1, Answer $tmp1: 3976727801
StrToMd5: Round 1, Answer $tmp1: 1496991403
StrToMd5: Round 1, Answer $tmp1: 785365157
StrToMd5: Round 1, Answer $tmp1: 708128447
StrToMd5: Round 1, Answer $tmp1: 1090829548
StrToMd5: Round 1, Answer $tmp1: 507743179
StrToMd5: Round 1, Answer $tmp1: 350415511
StrToMd5: Round 1, Answer $tmp1: 758105254
StrToMd5: Round 1, Answer $tmp1: 2024392292
StrToMd5: Round 1, Answer $tmp1: 2205205030
StrToMd5: Round 1, Answer $tmp1: 246492053
StrToMd5: Round 1, Answer $tmp1: 589028787
StrToMd5: Round 1, Answer $tmp1: 2592587921
StrToMd5: Round 1, Answer $tmp1: 2115641548
StrToMd5: Round 1, Answer $tmp1: 3631676176
StrToMd5: Round 2, Answer $tmp1: 1784287161
StrToMd5: Round 2, Answer $tmp1: 1701006001
StrToMd5: Round 2, Answer $tmp1: 2770721335
StrToMd5: Round 2, Answer $tmp1: 2262270538
StrToMd5: Round 2, Answer $tmp1: 2268326889
StrToMd5: Round 2, Answer $tmp1: 568927790
StrToMd5: Round 2, Answer $tmp1: 1828849176
StrToMd5: Round 2, Answer $tmp1: 577691891
StrToMd5: Round 2, Answer $tmp1: 4184934364
StrToMd5: Round 2, Answer $tmp1: 328992381
StrToMd5: Round 2, Answer $tmp1: 657433351
StrToMd5: Round 2, Answer $tmp1: 3937119657
StrToMd5: Round 2, Answer $tmp1: 3510949256
StrToMd5: Round 2, Answer $tmp1: 1378320286
StrToMd5: Round 2, Answer $tmp1: 3914302571
StrToMd5: Round 2, Answer $tmp1: 31869769
StrToMd5: Round 3, Answer $tmp1: 4058338996
StrToMd5: Round 3, Answer $tmp1: 3288109044
StrToMd5: Round 3, Answer $tmp1: 1892110870
StrToMd5: Round 3, Answer $tmp1: 107521821
StrToMd5: Round 3, Answer $tmp1: 961001941
StrToMd5: Round 3, Answer $tmp1: 409290396
StrToMd5: Round 3, Answer $tmp1: 1197999769
StrToMd5: Round 3, Answer $tmp1: 2383894880
StrToMd5: Round 3, Answer $tmp1: 288337030
StrToMd5: Round 3, Answer $tmp1: 1573508346
StrToMd5: Round 3, Answer $tmp1: 3912624502
StrToMd5: Round 3, Answer $tmp1: 988659220
StrToMd5: Round 3, Answer $tmp1: 1607546607
StrToMd5: Round 3, Answer $tmp1: 1478383357
StrToMd5: Round 3, Answer $tmp1: 2626854136
StrToMd5: Round 3, Answer $tmp1: 3933778205
StrToMd5: Round 4, Answer $tmp1: 2422522843
StrToMd5: Round 4, Answer $tmp1: 3421437809
StrToMd5: Round 4, Answer $tmp1: 3398617929
StrToMd5: Round 4, Answer $tmp1: 517644729
StrToMd5: Round 4, Answer $tmp1: 3981120703
StrToMd5: Round 4, Answer $tmp1: 2208039566
StrToMd5: Round 4, Answer $tmp1: 558860515
StrToMd5: Round 4, Answer $tmp1: 3871410182
StrToMd5: Round 4, Answer $tmp1: 1540357410
StrToMd5: Round 4, Answer $tmp1: 2069010446
StrToMd5: Round 4, Answer $tmp1: 2102830634
StrToMd5: Round 4, Answer $tmp1: 4139035227
StrToMd5: Round 4, Answer $tmp1: 141808929
StrToMd5: Round 4, Answer $tmp1: 1431334097
StrToMd5: Round 4, Answer $tmp1: 46728212
StrToMd5: Round 4, Answer $tmp1: 3909142066
22f8b86fbb71ced812e1839b47c18265
PHP MD5: 8af270b2847610e742b0791b53648c09
 
harsini
just joined
Posts: 2
Joined: Tue Oct 13, 2015 9:33 am

Re: Script MD5 Hash Generator

Sat Oct 24, 2015 11:53 am

Thanks for your nice hash function.Arrays defined like:
:local arrMd5State {}
should change to:
:local arrMd5State []
to work on ROS 6.25
 
fams
just joined
Posts: 2
Joined: Fri May 24, 2013 1:08 am

Re: Script MD5 Hash Generator

Thu Feb 11, 2016 5:24 pm

Thanks for the code, i patched the script to work as a function (v6.2+) debug as parameter and work with strings over 56bytes. Remember that MD5 is not collision resistent, i will write a SHA-1 version soon.
The first argument is the string, the second is a debug flag
# String message to MD5 Hash
# Creates a MD5 hash from a message string
# Version 1.00, 6/17/2012, Created by TealFrog
# Version 1.1 2/11/2016, Modified by FAMS
# Script tested and developed under MikroTik ROS 6.3 to 6.33
# 
#
# This software is identified as using and is based on the, "RSA Data Security, 
# Inc. MD5 Message-Digest Algorithm".  This program is a derived work from the RSA Data
# Security, Inc. MD5 Message-Digest Algorithm.
# See http://www.ietf.org/rfc/rfc1321.txt for further information.
#
# The author of this program makes no representations concerning either
# the merchantability of this software or the suitability of this
# software for any particular purpose or non-infringement.
# This program is provided "as is" without express or implied warranty of any kind.
# The author makes no representations or warranties of any kind as to the 
# completeness, accuracy, timeliness, availability, functionality and compliance
# with applicable laws. By using this software you accept the risk that the 
# information may be incomplete or inaccurate or may not meet your needs 
# and requirements. The author shall not be liable for any damages or 
# injury arising out of the use of this program. Use this program at your own risk. 
#
# MD5 has been shown to not be collision resistant, as such MD5 is not suitable 
# for certain applications involving security and/or cryptography, 
# see http://en.wikipedia.org/wiki/Md5 for additional information.
#
# $progName, Name of script, set appropriately
:global StrToMd5 do={

  :local progName "StrToMd5"
  :local strMessage $1
  # $strPrefix, Set to a prefix to add before MD5 hash, set "" for empty
  :local strPrefix ""

  # $strSuffix, Set to a suffix to add after MD5 hash, set "" for empty
  :local strSuffix ""
       # Set $Debug to 1 for additional output, set to zero to turn off debug
  :local Debug $2

  # $strHexValues, Used to create hexadecimal output
  :local strHexValues "0123456789abcdef"
  # To have uppercase hexadecimal A-F use the next line instead of the above
  # :local strHexValues "0123456789ABCDEF"

  # No futher modification required beyond this point unless customizing script
  # Start by defining constant values

  # ASCII Table $CharSet[0..127]
  :local arrCharSet ( "\00", "\01", "\02", "\03", "\04", "\05", "\06", "\07", \ 
                     "\08", "\09", "\0A", "\0B", "\0C", "\0D", "\0E", "\0F", \ 
                     "\10", "\11", "\12", "\13", "\14", "\15", "\16", "\17", \
                     "\18", "\19", "\1A", "\1B", "\1C", "\1D", "\1E", "\1F", \
                     "\20", "\21", "\22", "\23", "\24", "\25", "\26", "\27", \
                     "\28", "\29", "\2A", "\2B", "\2C", "\2D", "\2E", "\2F", \
                     "\30", "\31", "\32", "\33", "\34", "\35", "\36", "\37", \
                     "\38", "\39", "\3A", "\3B", "\3C", "\3D", "\3E", "\3F", \
                     "\40", "\41", "\42", "\43", "\44", "\45", "\46", "\47", \ 
                     "\48", "\49", "\4A", "\4B", "\4C", "\4D", "\4E", "\4F", \
                     "\50", "\51", "\52", "\53", "\54", "\55", "\56", "\57", \
                     "\58", "\59", "\5A", "\5B", "\5C", "\5D", "\5E", "\5F", \
                     "\60", "\61", "\62", "\63", "\64", "\65", "\66", "\67", \
                     "\68", "\69", "\6A", "\6B", "\6C", "\6D", "\6E", "\6F", \
                     "\70", "\71", "\72", "\73", "\74", "\75", "\76", "\77", \
                     "\78", "\79", "\7A", "\7B", "\7C", "\7D", "\7E", "\7F" ) 

  # k[i] = floor(abs(sin(i + 1))  4294967296) 
  # Or just use the following table $k[0..63]:
  :local k ( 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, \
            0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, \
            0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, \
            0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821, \
            0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, \
            0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, \
            0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, \
            0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A, \
            0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, \
            0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70, \
            0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, \
            0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665, \
            0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, \
            0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1, \
            0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1, \
            0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391 )

  :local a 0x67452301 
  :local b 0xEFCDAB89
  :local c 0x98BADCFE
  :local d 0x10325476

  :local AA 0x67452301
  :local BB 0xEFCDAB89
  :local CC 0x98BADCFE
  :local DD 0x10325476

  :local s1 (  7, 12, 17, 22 )
  :local s2 (  5,  9, 14, 20 )
  :local s3 (  4, 11, 16, 23 )
  :local s4 (  6, 10, 15, 21 )

  :local i 0
  :local j 0
  :local x 0
  :local S 0
  :local T 0
  :local lcv 0
  :local tmp1 0

  :local arrMd5State []
  :local arrWordArray []
  :local ch ""
  :local iByteCount 0
  :local iCharVal 3
  :local iDec 0
  :local iHexDigit 8
  :local iMd5State 0
  :local lBytePosition 0
  :local lMessageLength 0
  :local lNumberOfWords 0        
  :local lShiftedVal 0
  :local lWordArray []
  :local lWordArrLen 0
  :local lWordCount 0
  :local sHex ""
  :local sMd5Hash ""
  :local sMd5Output ""
  :local strWordArray ""

  # Start of main program and message loop
  if ( $Debug > 0 ) do={
    :put "$progName: Running..."
    :put "$progName: Message: $strMessage"
  }
  :set ch ""
  :set lShiftedVal 0
  :set lWordCount 0
  :set iByteCount 0
  :set iCharVal 3
  :set lBytePosition 0
  :set lMessageLength [ :len $strMessage ]
  :set lNumberOfWords ( ( ( ( $lMessageLength + 8 ) / 64 ) + 1 ) * 16 )        
  :set strWordArray ""
  :set arrWordArray []

  # Convert to word array 
  :for i from=1 to=($lNumberOfWords) do={
    :set strWordArray ("0," . $strWordArray)
  }
  :set strWordArray  [ :pick $strWordArray 0 ( [ :len $strWordArray ] - 1 ) ]
  :set arrWordArray [ :toarray $strWordArray ]
  :if ( $Debug > 0 ) do={
    :put ("$progName: Message Length: " . $lMessageLength)
    :put ("$progName: Number of Words: " . $lNumberOfWords)
    :put ("$progName: strWordArray $strWordArray")
  }
  :while ($iByteCount < $lMessageLength) do={
    :set lWordCount ($iByteCount / 4)
    :set lBytePosition (($iByteCount % 4) * 8)
    :if (($lBytePosition < 0) or ($lBytePosition > 31)) do={
      :error ( "$progName: Error --  Calculating byte position " . \
          "# $lBytePosition, must be 0 thru 31." )
    }
    :set ch [ :pick $strMessage $iByteCount ]
    :if ( [ :len [ :find $arrCharSet $ch ] ] > 0 ) do={
      :set iCharVal ([ :tonum [ :find $arrCharSet $ch ] ])
    } else={
      :error "$progName: Error -- Input contains undefined ASCII value."
    }
    :if ( $Debug > 0 ) do={
      :put ( "$progName: parsed character \$ch: '$ch' " . \
        "ASCII value \$iCharVal: $iCharVal" )
    }
    :set lShiftedVal ((($iCharVal) << ($lBytePosition)) | \
                   (($iCharVal) >> (32-($lBytePosition))))
    :if ($iByteCount = 0) do={
      :set lShiftedVal (([ :tonum $lShiftedVal ] + 0) & 0xFFFFFFFF)
      :set arrWordArray (([ :tonum $lShiftedVal ]), \
                       [ :pick $arrWordArray 1 [ :len $arrWordArray] ])
    } else={
      :set lShiftedVal (([ :tonum [ :pick $arrWordArray $lWordCount] ] + 0) | \
                     ([ :tonum $lShiftedVal ] + 0))
      :set lShiftedVal (([ :tonum $lShiftedVal ] + 0) & 0xFFFFFFFF)
      :set arrWordArray  ([ :pick $arrWordArray 0 $lWordCount ], $lShiftedVal, \
         [ :pick $arrWordArray ([ :tonum $lWordCount ] + 1) [ :len $arrWordArray] ])   
    }
    :set iByteCount ( $iByteCount + 1 )
  }
  :set lWordCount ( $iByteCount / 4 )
  :set lBytePosition ( ( $iByteCount % 4 ) * 8 )
  :set lShiftedVal [ :pick $arrWordArray $lWordCount ]

  :set lShiftedVal ( ( [ :tonum [ :pick $arrWordArray $lWordCount ] ] + 0 ) | \
                   ( ( 0x80 << $lBytePosition ) | \
                 ( 0x80 >> ( 32 - $lBytePosition ) ) ) ) 

  :set arrWordArray  ( ( [ :pick $arrWordArray 0 $lWordCount ]  ),  \
                       [ :tonum $lShiftedVal ], \
                     ( [ :pick $arrWordArray ( [ :tonum $lWordCount ] + 1 ) \
                [ :len $arrWordArray ] ] ) ) 
                
  :set arrWordArray  [ :toarray ( ( [ :pick $arrWordArray 0 ($lNumberOfWords - 2) ] ), \
                              ( ( ( [ :tonum $lMessageLength ] + 0 ) << 3 ) | \
                       ( ( [ :tonum $lMessageLength ] + 0 ) >> 29 ) ), \
                       ( ( [ :tonum $lMessageLength ] + 0 )  >> 29 ) ) ] 
  :set lWordArray [ :toarray $arrWordArray ]
  :set lWordArrLen ( ( [ :len $lWordArray ] ) - 1 )
  :if ($Debug >0 ) do={
    :put "lWordArrLen $lWordArrLen"
  }
  ### Main Loop ###
  :set tmp1 0
  :set x 0
  :set T 0
  :set S 0
  :set i 0
  :set j 0
  :local iteration 0
  #:set a 0x67452301 
  #:set b 0xEFCDAB89
  #:set c 0x98BADCFE
  #:set d 0x10325476
  #Loop Principal
  :if ( $Debug >0 ) do={
    :put $lWordArray
  }
  :for lcv from=0 to=( $lWordArrLen ) step=16 do={
    :set AA [ :tonum $a ]
    :set BB [ :tonum $b ]
    :set CC [ :tonum $c ]
    :set DD [ :tonum $d ]
    :if ( $Debug > 0 ) do={
      :put $iteration
    }
    :local chuckoffset ($iteration * 16)
  ### Round 1 ### 
    :for i from=0 to=15 do={
      :set x ( [ :tonum [ :pick $lWordArray (( $i & 15 ) + $chuckoffset) ] ] + 0 )
      :set T ( [ :tonum [ :pick $k $i ] ] + 0 )
      :set S ( [ :tonum [ :pick $s1 ( $i & 3 ) ] ] + 0 )
  # Next line is an alternate mmethod, instead of the line after it     
  #         :set tmp1 ( ( (($b & $c) | (((($b + 1) * -1)) & $d)) + $a + $T + $x ) & 0xFFFFFFFF )
      :set tmp1 ( ( ( $d ^ ( $b & ( $c ^ $d ) ) ) + $a + $T + $x ) & 0xFFFFFFFF )
      :set tmp1 (((tmp1 << $S ) | (($tmp1 >> (32 - $S)))) & 0xFFFFFFFF)
      :set tmp1 ( ( $tmp1 + $b ) & 0xFFFFFFFF )
      :if ( $Debug > 0 ) do={         
         :put ("$progName: Round 1, Answer \$tmp1: $tmp1") 
      }            
  # Rotate a,b,c,d params positions, e.g. d, a, b, c ... c, d, a, b ... b, c, d, a 
  # and a gets new value from tmp1
      :set a ( ( [ :tonum $d ] + 0 ) & 0xFFFFFFFF )
      :set d ( ( [ :tonum $c ] + 0 ) & 0xFFFFFFFF )
      :set c ( ( [ :tonum $b ] + 0 ) & 0xFFFFFFFF )
      :set b ( ( [ :tonum $tmp1 ] + 0 ) & 0xFFFFFFFF )
    }

  ### Round 2 ###
    :set j 1
    :for i from=0 to=15 do={
      :set x ( [ :tonum [ :pick $lWordArray (( ( [ :tonum $j ] + 0 ) & 15 ) + $chuckoffset ) ] ] + 0 )
      :set T ( [ :tonum [ :pick $k ( $i + 16 ) ] ] + 0 )
      :set S ( [ :tonum [ :pick $s2 ( $i & 3 ) ] ] + 0 )
      :set tmp1 ( ( ( $c ^ ( $d & ( $b ^ $c ) ) ) + $a + $T + $x ) & 0xFFFFFFFF )
      :set tmp1 (((tmp1 << $S ) | (($tmp1 >> (32 - $S)))) & 0xFFFFFFFF)
      :set tmp1 ( ( $tmp1 + $b ) & 0xFFFFFFFF )
      :if ( $Debug > 0 ) do={         
         :put ("$progName: Round 2, Answer \$tmp1: $tmp1") 
      }
  # Rotate a,b,c,d param positions, e.g. d, a, b, c ... c, d, a, b ... b, c, d, a
      :set a ( ( [ :tonum $d ] + 0 ) & 0xFFFFFFFF )
      :set d ( ( [ :tonum $c ] + 0 ) & 0xFFFFFFFF )
      :set c ( ( [ :tonum $b ] + 0 ) & 0xFFFFFFFF )
      :set b ( ( [ :tonum $tmp1 ] + 0 ) & 0xFFFFFFFF )
      :set j ( $j + 5 )
    }
   
  ### Round 3 ###
    :set j 5
    :for i from=0 to=15 do={
      :set x ( [ :tonum [ :pick $lWordArray ( ( ( [ :tonum $j ] + 0 ) & 15 ) + $chuckoffset) ] ] + 0 )
      :set T ( [ :tonum [ :pick $k ( $i + 32 ) ] ] + 0 )
      :set S ( [ :tonum [ :pick $s3 ( $i & 3 ) ] ] + 0 )
      :set tmp1 ( ( ( $b ^ $c ^ $d ) + $a + $T + $x ) & 0xFFFFFFFF )
      :set tmp1 (((tmp1 << $S ) | (($tmp1 >> (32 - $S)))) & 0xFFFFFFFF)
      :set tmp1 ( ( $tmp1 + $b ) & 0xFFFFFFFF )
      :if ( $Debug > 0 ) do={         
         :put ("$progName: Round 3, Answer \$tmp1: $tmp1") 
      }            
  # Rotate a,b,c,d param positions, e.g. d, a, b, c ... c, d, a, b ... b, c, d, a
      :set a ( ( [ :tonum $d ] + 0) & 0xFFFFFFFF )
      :set d ( ( [ :tonum $c ] + 0) & 0xFFFFFFFF )
      :set c ( ( [ :tonum $b ] + 0) & 0xFFFFFFFF )
      :set b ( ( [ :tonum $tmp1 ] + 0) & 0xFFFFFFFF )
      :set j ( $j + 3 )
    }
   
  ### Round 4 ###
    :set j 0
    :for i from=0 to=15 do={
      :set x ( [ :tonum [ :pick $lWordArray  ( ( ( [ :tonum $j ] + 0 ) & 15 ) + $chuckoffset ) ] ] + 0 )
      :set T ( [ :tonum [ :pick $k ( $i + 48 ) ] ] + 0 )
      :set S ( [ :tonum [ :pick $s4 ( $i & 3 ) ] ] + 0 )
  # Next line is alternate method to the line following     
  #         :set tmp1 ( $c ^ ( $b | ( ( $d & 0xFFFFFFFF ) ^ 0xFFFFFFFF ) ) )
      :set tmp1 ( ( $c ^ ( $b | ( -1 * ( $d + 1 ) ) ) ) & 0xFFFFFFFF )
      :set tmp1 ( ( $tmp1 + $a + $T + $x ) & 0xFFFFFFFF )
      :set tmp1 ( ((tmp1 << $S ) | (($tmp1 >> (32 - $S)))) & 0xFFFFFFFF )
      :set tmp1 ( ( $tmp1 + $b ) & 0xFFFFFFFF )
      :if ( $Debug > 0 ) do={         
         :put ("$progName: Round 4, Answer \$tmp1: $tmp1") 
      }            
  # Rotate a,b,c,d param positions, e.g. d, a, b, c ... c, d, a, b ... b, c, d, a
      :set a ( ( [ :tonum $d ] + 0) & 0xFFFFFFFF )
      :set d ( ( [ :tonum $c ] + 0) & 0xFFFFFFFF )
      :set c ( ( [ :tonum $b ] + 0) & 0xFFFFFFFF )
      :set b ( ( [ :tonum $tmp1 ] + 0) & 0xFFFFFFFF )
      :set j ( $j + 7 )
    }
    :if ( $Debug > 0 ) do={      
      :put "Iteration $iteration = $a | $b | $c | $d"
    }
    :set a ( ( $a + $AA ) & 0xFFFFFFFF )    
    :set b ( ( $b + $BB ) & 0xFFFFFFFF )    
    :set c ( ( $c + $CC ) & 0xFFFFFFFF )    
    :set d ( ( $d + $DD ) & 0xFFFFFFFF ) 
    :set iteration ( $iteration +1 ) 
  }

  :set arrMd5State [ :toarray "$a, $b, $c, $d" ]
  :set sMd5Hash ""
  :set sMd5Output ""
  :set iDec 0
  :set iMd5State 0
  :set sHex ""
  :for i from=0 to=3 do={
    :set iMd5State [ :pick $arrMd5State $i ]      
    :for j from=0 to=3 do={
      :set iMd5State ( [ :tonum $iMd5State ] & 0xFFFFFFFF )
      :if ( $j < 1 ) do={
         :set iDec ( [ :tonum $iMd5State ] & 255 )
      } else={
        :set iDec ( ( $iMd5State & 0x7FFFFFFE ) / ( 2 << ( ( $j * 8 ) - 1 ) ) )
        :if ( ( $iMd5State & 0x80000000 ) > 0 ) do={
          :set iDec ( $iDec | ( 0x40000000 /  ( 2 << ( ( $j * 8 ) - 2 ) ) ) )
        }
        :set iDec ( $iDec & 0xFF ) 
      } 
      :set sHex ""
      :for k from=0 to=( 4 * ( $iHexDigit - 1 ) ) step=4 do={
        :set sHex ( [ :pick [ :tostr $strHexValues ] \
        ( ( $iDec >> $k ) & 0xF ) \ 
        ( ( ( $iDec >> $k ) & 0xF ) + 1 ) ] . $sHex ) 
      }
      :set sHex [ :tostr $sHex ]
      :set sHex [ :pick $sHex ( [ :len $sHex ] - 2 ) [ :len $sHex ] ]
      :set sMd5Output ( $sMd5Output . $sHex )     
    }
  }
  # Modify next line to customize MD5 output string     
  :put [( [ :tostr $strPrefix ] . [ :tostr $sMd5Output ] . [ :tostr $strSuffix ] )]
  if ( $Debug > 0 ) do={
    :put "$progName: Done."
  }
}
 
sejtam
Frequent Visitor
Frequent Visitor
Posts: 66
Joined: Sun Dec 14, 2014 4:23 pm

Re: Script MD5 Hash Generator

Tue Jan 09, 2018 3:11 pm

I am not so fluent in The ROS language. Could someone show an example
how to call this as a function?

I looked at

https://wiki.mikrotik.com/wiki/Use_Func ... CMD_Script

But that method is somewhat different?

thanks

Who is online

Users browsing this forum: No registered users and 20 guests