Download MetaTrader 5
To add comments, please log in or register
Join MQL5 Cloud Network affiliate program and make money!
Point Zero
872
Point Zero 2014.02.10 19:35 

Good afternoon,

I have been posting today like crazy (err, sorry about that). I had a perfectly working MD5 function, which now returns a wrong md5 value (it returns a value, but it is a wrong one)

I guess it makes little sense to paste the function, but just in case. Does anybody have another Md5 implementation working well under b600?

I would really appreciate it. Thanks in advance!

EDIT: As it turns out, this function works perfectly and I am simply over-tired and with too much caffeine on my bloodstream.

string MD5(string str)
{
    int len = StringLen(str);
    int index = len % 64; //mod 64
    int count = (len - index) / 64;
    
    int a = (int) 0x67452301, b = (int) 0xEFCDAB89, c = (int) 0x98BADCFE, d = 0x10325476;
    int buff[16], last[16], i, k, last_char[4], last_index;
    string item;
    for (i = 0; i < count; i++)
    {
        item = StringSubstr(str, i * 64, 64);
        StringToIntegerArray(buff, item);
        MD5Transform(a, b , c, d, buff);
    }
    ArrayInitialize(last, 0);
    ArrayInitialize(last_char, 0);
    last_index = 0;
    if (index > 0) {
      int last_num = index % 4;
      count = index - last_num;
      if (count > 0) {
         item = StringSubstr(str, i * 64, count);
         last_index = StringToIntegerArray(last, item);
      }
      for (k = 0; k < last_num; k++)
      {
          last_char[k] = StringGetChar(str, i * 64 + count + k); 
      }
    }
    last_char[k] = 0x80;
    last[last_index] = CharToInteger(last_char);
    if (index >= 56) {
        MD5Transform(a, b , c, d, last);
        ArrayInitialize(last, 0);
    }
    last[14] =  len << 3;
    last[15] =  ((len >> 1) & 0x7fffffff) >> 28;
    MD5Transform(a, b , c, d, last);
    return (StringConcatenate(IntegerToString(a) , IntegerToString(b) , IntegerToString(c) ,  IntegerToString(d)));
}

int F(int x, int y, int z) 
{ 
    return ((x & y) | ((~x) & z)); 
}

int G(int x, int y, int z) 
{ 
    return ((x & z) | (y & (~z))); 
}

int H(int x, int y, int z) 
{ 
    return ((x ^ y ^ z));
}

int I(int x, int y, int z) 
{ 
    return ((y ^ (x | (~z))));
}

int AddUnsigned(int a, int b)
{
    int c = a + b;
    return (c);
}

int FF(int a, int b, int c, int d, int x, int s, int ac) 
{
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
        return (AddUnsigned(RotateLeft(a, s), b));
}

int GG(int a, int b, int c, int d, int x, int s, int ac) 
{
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
        return (AddUnsigned(RotateLeft(a, s), b));
}

int HH(int a, int b, int c, int d, int x, int s, int ac) 
{
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
        return (AddUnsigned(RotateLeft(a, s), b));
}

int II(int a, int b, int c, int d, int x, int s, int ac) 
{
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
        return (AddUnsigned(RotateLeft(a, s), b));
}

int RotateLeft(int lValue, int iShiftBits) 
{ 
    if (iShiftBits == 32) return (lValue);
    int result = (lValue << iShiftBits) | (((lValue >> 1) & 0x7fffffff) >> (31 - iShiftBits));
    return (result);
}

/*
* assume: len % 4 == 0; 
*/
int StringToIntegerArray(int &output[], string l_input)
{
   int len;
   int i, j;
   len = StringLen(l_input);
   if (len % 4 !=0) len = len - len % 4;
   int size = ArraySize(output);
   if (size < len/4) {
       ArrayResize(output, len/4);
   }
   for (i = 0, j = 0; j < len; i++, j += 4) 
   {
       output[i] = (StringGetChar(l_input, j)) | ((StringGetChar(l_input, j+1)) << 8) 
                | ((StringGetChar(l_input, j+2)) << 16) | ((StringGetChar(l_input, j+3)) << 24);
   }
   return(len/4);
}

string IntegerToString(int integer_number)
{
   string hex_string="", hex_item;
   int output[4];
   output[0] = integer_number & 0xff;
   for (int k = 1; k < 4; k++) 
   {
       output[k] = (((integer_number >> 1) & 0x7fffffff) >> (k*8 -1)) & 0xff;
   }
   for (int i = 0; i < 4; i++)
   {
       hex_item = Dec2Hex(output[i]);
       hex_string = StringConcatenate(hex_string, hex_item);
   }
   return(hex_string);
}

/**
*assume num is little than 256
*/

string Dec2Hex(int num)
{
    int modnum;
    string hex;
    for (int i =0; i < 2; i++)
    {
        modnum = num % 16;
        num = (num - modnum) / 16;
        hex = StringConcatenate(IntToHexString(modnum), hex);
    }
    return (hex);
}

string IntToHexString(int a)
{
    string hex = "0";
    int ascii;
    if (a < 10) {
       ascii = '0' + a;
    } else {
       ascii = 'a' + a - 10;
    }
    return (StringSetChar(hex, 0, ascii));
}

int CharToInteger(int &a[])
{
    return ((a[0]) | (a[1] << 8) | (a[2] << 16) | (a[3] << 24));
}

/*
* assume: ArraySize(x) == 16
*/
void MD5Transform(int &a, int &b, int &c, int &d, int &x[])
{
   int AA, BB, CC, DD;
        int S11=7, S12=12, S13=17, S14=22;
        int S21=5, S22=9 , S23=14, S24=20;
        int S31=4, S32=11, S33=16, S34=23;
        int S41=6, S42=10, S43=15, S44=21;

   AA=a; BB=b; CC=c; DD=d;
   a=FF(a,b,c,d,x[0], S11, (int) 0xD76AA478);
   d=FF(d,a,b,c,x[1], S12, (int) 0xE8C7B756);
   c=FF(c,d,a,b,x[2], S13, (int) 0x242070DB);
   b=FF(b,c,d,a,x[3], S14, (int) 0xC1BDCEEE);
   a=FF(a,b,c,d,x[4], S11, (int) 0xF57C0FAF);
   d=FF(d,a,b,c,x[5], S12, (int) 0x4787C62A);
   c=FF(c,d,a,b,x[6], S13, (int) 0xA8304613);
   b=FF(b,c,d,a,x[7], S14, (int) 0xFD469501);
   a=FF(a,b,c,d,x[8], S11, (int) 0x698098D8);
   d=FF(d,a,b,c,x[9], S12, (int) 0x8B44F7AF);
   c=FF(c,d,a,b,x[10],S13, (int) 0xFFFF5BB1);
   b=FF(b,c,d,a,x[11],S14, (int) 0x895CD7BE);
   a=FF(a,b,c,d,x[12],S11, (int) 0x6B901122);
   d=FF(d,a,b,c,x[13],S12, (int) 0xFD987193);
   c=FF(c,d,a,b,x[14],S13, (int) 0xA679438E);
   b=FF(b,c,d,a,x[15],S14, (int) 0x49B40821);
   
   a=GG(a,b,c,d,x[1], S21, (int) 0xF61E2562);
   d=GG(d,a,b,c,x[6], S22, (int) 0xC040B340);
   c=GG(c,d,a,b,x[11],S23, (int) 0x265E5A51);
   b=GG(b,c,d,a,x[0], S24, (int) 0xE9B6C7AA);
   a=GG(a,b,c,d,x[5], S21, (int) 0xD62F105D);
   d=GG(d,a,b,c,x[10],S22, (int) 0x2441453);
   c=GG(c,d,a,b,x[15],S23, (int) 0xD8A1E681);
   b=GG(b,c,d,a,x[4], S24, (int) 0xE7D3FBC8);
   a=GG(a,b,c,d,x[9], S21, (int) 0x21E1CDE6);
   d=GG(d,a,b,c,x[14],S22, (int) 0xC33707D6);
   c=GG(c,d,a,b,x[3], S23, (int) 0xF4D50D87);
   b=GG(b,c,d,a,x[8], S24, (int) 0x455A14ED);
   a=GG(a,b,c,d,x[13],S21, (int) 0xA9E3E905);
   d=GG(d,a,b,c,x[2], S22, (int) 0xFCEFA3F8);
   c=GG(c,d,a,b,x[7], S23, (int) 0x676F02D9);
   b=GG(b,c,d,a,x[12],S24, (int) 0x8D2A4C8A);

   a=HH(a,b,c,d,x[5], S31, (int) 0xFFFA3942);
   d=HH(d,a,b,c,x[8], S32, (int) 0x8771F681);
   c=HH(c,d,a,b,x[11],S33, (int) 0x6D9D6122);
   b=HH(b,c,d,a,x[14],S34, (int) 0xFDE5380C);
   a=HH(a,b,c,d,x[1], S31, (int) 0xA4BEEA44);
   d=HH(d,a,b,c,x[4], S32, (int) 0x4BDECFA9);
   c=HH(c,d,a,b,x[7], S33, (int) 0xF6BB4B60);
   b=HH(b,c,d,a,x[10],S34, (int) 0xBEBFBC70);
   a=HH(a,b,c,d,x[13],S31, (int) 0x289B7EC6);
   d=HH(d,a,b,c,x[0], S32, (int) 0xEAA127FA);
   c=HH(c,d,a,b,x[3], S33, (int) 0xD4EF3085);
   b=HH(b,c,d,a,x[6], S34, (int) 0x4881D05);
   a=HH(a,b,c,d,x[9], S31, (int) 0xD9D4D039);
   d=HH(d,a,b,c,x[12],S32, (int) 0xE6DB99E5);
   c=HH(c,d,a,b,x[15],S33, (int) 0x1FA27CF8);
   b=HH(b,c,d,a,x[2], S34, (int) 0xC4AC5665);

   a=II(a,b,c,d,x[0], S41, (int) 0xF4292244);
   d=II(d,a,b,c,x[7], S42, (int) 0x432AFF97);
   c=II(c,d,a,b,x[14],S43, (int) 0xAB9423A7);
   b=II(b,c,d,a,x[5], S44, (int) 0xFC93A039);
   a=II(a,b,c,d,x[12],S41, (int) 0x655B59C3);
   d=II(d,a,b,c,x[3], S42, (int) 0x8F0CCC92);
   c=II(c,d,a,b,x[10],S43, (int) 0xFFEFF47D);
   b=II(b,c,d,a,x[1], S44, (int) 0x85845DD1);
   a=II(a,b,c,d,x[8], S41, (int) 0x6FA87E4F);
   d=II(d,a,b,c,x[15],S42, (int) 0xFE2CE6E0);
   c=II(c,d,a,b,x[6], S43, (int) 0xA3014314);
   b=II(b,c,d,a,x[13],S44, (int) 0x4E0811A1);
   a=II(a,b,c,d,x[4], S41, (int) 0xF7537E82);
   d=II(d,a,b,c,x[11],S42, (int) 0xBD3AF235);
   c=II(c,d,a,b,x[2], S43, (int) 0x2AD7D2BB);
   b=II(b,c,d,a,x[9], S44, (int) 0xEB86D391);

   a=AddUnsigned(a, AA); b=AddUnsigned(b, BB);
   c=AddUnsigned(c, CC); d=AddUnsigned(d, DD);
}
ydrol
595
ydrol 2014.02.10 19:47  

EDIT: As it's solved, Better ignore my response below though - but I cant help but wonder if you MD5Sum binary data what will happen :)

-----------

Suspect it is your StringGetChar causing issues. As this now returns a 16bit value, because strings are UTF-16. Wide Unicode.

If you are summing binary data you will need to change to using char arrays, and process those.

First convert your string using StringToCharArray, then replace StringGetChar with the direct index on the array.

You might probably find it all runs a lot quicker too?

/
To add comments, please log in or register