MD5 на MQL4/5 (CryptEncode)

 
Подскажите, пожалуйста, как в MQL4/5 получить MD5 от строки в виде string, на манер PHP-ной md5()?

Для пробы набросал такую функцию:
string md5(const string value)
{
   uchar result[];
   
   const uchar key[1]= {0};
   
   uchar data[];
   StringToCharArray(value, data);

   CryptEncode(CRYPT_HASH_MD5, data, key, result);
   
   string resultStr = "";
   for(int i = 0; i < ArraySize(result); i++)
   {
      resultStr = StringConcatenate(resultStr, StringFormat("%02x", result[i]), ".");
   }
   
   return resultStr;
}
Вызов делаю так:
Alert
(
        md5("123") 
        + "\r\n" 
        + "20.2c.b9.62.ac.59.07.5b.96.4b.07.15.2d.23.4b.70"
);

Результат вызова:

14.4f.22.14.06.1a.c1.76.35.86.13.8e.3b.42.00.71.
20.2c.b9.62.ac.59.07.5b.96.4b.07.15.2d.23.4b.70

Здесь вторая строка - md5 хэш от "123". А первая строка - результат моей функции. Как видно, она выдаёт совсем не то значение.

Байты отделил точками, чтобы было нагляднее в алерте, разумеется в итоге их не будет.


Понимаю, что где-то скорее всего я не прав, но где?
 
https://www.mql5.com/ru/code/1553
MD5 Hash
MD5 Hash
  • голосов: 28
  • 2013.02.25
  • o_O
  • www.mql5.com
Вычисление 32-символьной строки MD5-хеша от переданного байтового массива
 
Ура, нашел как,
помучился но нашел ))

Вот держите (немного изменил структуру):
string md5(const string value, const string key_string)
{
   uchar key[];
   int key_size = StringToCharArray(key_string, key);
   ArrayResize(key, key_size - 1); 
   
   uchar data[];
   int data_size = StringToCharArray(value, data);
   ArrayResize(data, data_size - 1);

   uchar result[];
   string resultStr = "";
   int res_size = CryptEncode(CRYPT_HASH_MD5, data, key, result);
   
   for(int i = 0; i < res_size; ++i)
   {
      resultStr = StringConcatenate(resultStr, StringFormat("%02x", result[i]), ".");
   }
   
   return resultStr;
}
 
sergeev:
https://www.mql5.com/ru/code/1553
Спасибо, да, беглый поиск выводил эту ссылку первой в поиске. Плюс самописная реализация у меня уже несколько лет есть.

Но сейчас захотелось таки завести нативную функцию, не зря же MQ её реализовали? :)

upd 27.02.2015: Впрочем, если бы я с должным вниманием посмотрел на пример вызова варианта по ссылке, то должен был бы заметить про "\0".


Ура, нашел как,
помучился но нашел ))

Вот держите (немного изменил структуру):

Спасибо!

Долго бы я мучался :)

Благодаря Вам примерно так будет у меня в итоге:

string md5(const string value)
{       
   uchar data[];
   StringToCharArray(value, data);
   ArrayResize(data, ArraySize(data) - 1);

   const uchar key[1] = {0};   
   
   uchar result[];
   CryptEncode(CRYPT_HASH_MD5, data, key, result);
   
   string resultStr = "";
   for(int i = 0; i < ArraySize(result); i++)
   {
      resultStr = StringConcatenate(resultStr, StringFormat("%02x", result[i]));
   }
   
   return resultStr;
}

Проверил, работает.

 

А вот ещё пока неразрешимая для меня загадка появилась - как получить md5 от "" (пустой строки) при помощи CryptEncode()? :)

Как известно, это "d41d8cd98f00b204e9800998ecf8427e".

Последний вариант функции выше вернёт пустую строку. Если убрать ArrayResize, то опять-таки ожидаемо не то получим на выходе.


Самый простой путь - захардкорить - итак понятен. Но вопрос именно в том, как получить такой результат применением нативной функции?  Как говорится, есть идеи?


P.S. вчерашний вариант немного изменил. Мне кажется, адекватней будет не делать ArrayResize, а задать длину строки сразу в StringToCharArray. Поэтому (и с учётом проблемы с пустой строкой) пока крайний вариант у меня такой:

string md5(const string value)
{
   const string EMPTY_MD5 = "d41d8cd98f00b204e9800998ecf8427e";
   if(value == "")
   {
      return EMPTY_MD5;
   }
   
   uchar result[];
   
   const uchar key[1]= {0};
   
   uchar data[];
   StringToCharArray(value, data, 0, StringLen(value));
   
   CryptEncode(CRYPT_HASH_MD5, data, key, result);
   
   string resultStr = "";
   for(int i = 0; i < ArraySize(result); i++)
   {
      resultStr = StringConcatenate(resultStr, StringFormat("%02x", result[i]));
   }
   
   return resultStr;
}
 
Sergey Eremin #:

пока крайний вариант у меня такой:


Поскольку ключ при расчете MD5 не используется, можно его так задать:

const uchar key[]={};
Причина обращения: