446 lines
12 KiB
Plaintext
446 lines
12 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// ----------------------------------------------
|
|
// Name: XSCMD5
|
|
// Description: Provides MD5 Hashing Requirements ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://www.saherelm.ir"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//
|
|
// START Definitions ...
|
|
//
|
|
|
|
//
|
|
static uchar _md5_PADDING[64] =
|
|
{
|
|
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
|
|
//
|
|
#define _md5_F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
|
#define _md5_G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
|
#define _md5_H(x, y, z) ((x) ^ (y) ^ (z))
|
|
#define _md5_I(x, y, z) ((y) ^ ((x) | (~z)))
|
|
#define _md5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
|
|
|
//
|
|
#define _md5_FF(a, b, c, d, x, s, ac) \
|
|
{ \
|
|
(a) += _md5_F((b), (c), (d)) + (x) + (uint)(ac); \
|
|
(a) = _md5_ROTATE_LEFT((a), (s)); \
|
|
(a) += (b); \
|
|
}
|
|
|
|
//
|
|
#define _md5_GG(a, b, c, d, x, s, ac) \
|
|
{ \
|
|
(a) += _md5_G((b), (c), (d)) + (x) + (uint)(ac); \
|
|
(a) = _md5_ROTATE_LEFT((a), (s)); \
|
|
(a) += (b); \
|
|
}
|
|
|
|
//
|
|
#define _md5_HH(a, b, c, d, x, s, ac) \
|
|
{ \
|
|
(a) += _md5_H((b), (c), (d)) + (x) + (uint)(ac); \
|
|
(a) = _md5_ROTATE_LEFT((a), (s)); \
|
|
(a) += (b); \
|
|
}
|
|
|
|
//
|
|
#define _md5_II(a, b, c, d, x, s, ac) \
|
|
{ \
|
|
(a) += _md5_I((b), (c), (d)) + (x) + (uint)(ac); \
|
|
(a) = _md5_ROTATE_LEFT((a), (s)); \
|
|
(a) += (b); \
|
|
}
|
|
|
|
//
|
|
#define _md5_INIT_STATE_0 0x67452301
|
|
#define _md5_INIT_STATE_1 0xefcdab89
|
|
#define _md5_INIT_STATE_2 0x98badcfe
|
|
#define _md5_INIT_STATE_3 0x10325476
|
|
|
|
//
|
|
#define _md5_S11 7
|
|
#define _md5_S12 12
|
|
#define _md5_S13 17
|
|
#define _md5_S14 22
|
|
|
|
//
|
|
#define _md5_S21 5
|
|
#define _md5_S22 9
|
|
#define _md5_S23 14
|
|
#define _md5_S24 20
|
|
|
|
//
|
|
#define _md5_S31 4
|
|
#define _md5_S32 11
|
|
#define _md5_S33 16
|
|
#define _md5_S34 23
|
|
|
|
//
|
|
#define _md5_S41 6
|
|
#define _md5_S42 10
|
|
#define _md5_S43 15
|
|
#define _md5_S44 21
|
|
|
|
//
|
|
// END Definitions ...
|
|
//
|
|
|
|
//
|
|
// XCMD5 a library for Hashing ...
|
|
class XCMD5
|
|
{
|
|
//
|
|
// Public Provides ...
|
|
public:
|
|
//
|
|
// Protected Provides ...
|
|
|
|
//
|
|
// Constructor ...
|
|
XCMD5(void)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XCMD5(void)
|
|
{
|
|
}
|
|
|
|
//
|
|
// Hash Specified Char Array ...
|
|
string Hash(
|
|
uchar &mSource[], // Specify Char Array to Hash
|
|
int mLength = 0 // Specify Length of Char Array which required to hash
|
|
)
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
int sourceCount = ArraySize(mSource);
|
|
|
|
//
|
|
// Validate Args ...
|
|
if (
|
|
sourceCount <= 0 ||
|
|
(sourceCount > 0 && mLength > sourceCount))
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Normalize Args ...
|
|
if (mLength == 0)
|
|
{
|
|
mLength = sourceCount;
|
|
}
|
|
|
|
//
|
|
// Init MD5 ...
|
|
MD5Init();
|
|
|
|
//
|
|
// Update Buffer ...
|
|
MD5Update(mSource, mLength);
|
|
|
|
//
|
|
// Calculate Result ...
|
|
result = MD5Final();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Hash Specified String ...
|
|
string Hash(
|
|
string mSource // Specified String
|
|
)
|
|
{
|
|
//
|
|
string result = "";
|
|
|
|
//
|
|
// Converts String to Char Array ...
|
|
uchar bytes[];
|
|
StringToCharArray(
|
|
mSource,
|
|
bytes,
|
|
0,
|
|
StringLen(mSource));
|
|
|
|
//
|
|
result = Hash(
|
|
bytes,
|
|
ArraySize(bytes));
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
protected:
|
|
//
|
|
// Private Provides ...
|
|
private:
|
|
//
|
|
uint m_lMD5[4];
|
|
uint m_nCount[2];
|
|
uchar m_lpszBuffer[64];
|
|
|
|
//
|
|
// Convert Byte to DWord ...
|
|
void ByteToDWord(int &out[], uint &in[], uint len)
|
|
{
|
|
//
|
|
uint i = 0;
|
|
uint j = 0;
|
|
|
|
//
|
|
for (; j < len; i++, j += 4)
|
|
{
|
|
out[i] = (int)in[j] | (int)in[j + 1] << 8 | (int)in[j + 2] << 16 | (int)in[j + 3] << 24;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Convert DWord to Byte ...
|
|
void DWordToByte(uchar &out[], int &in[], uint len)
|
|
{
|
|
//
|
|
uint i = 0;
|
|
uint j = 0;
|
|
|
|
//
|
|
for (; j < len; i++, j += 4)
|
|
{
|
|
//
|
|
out[j] = (uchar)(in[i] & 0xff);
|
|
out[j + 1] = (uchar)((in[i] >> 8) & 0xff);
|
|
out[j + 2] = (uchar)((in[i] >> 16) & 0xff);
|
|
out[j + 3] = (uchar)((in[i] >> 24) & 0xff);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Init MD5 Array ...
|
|
void MD5Init()
|
|
{
|
|
//
|
|
ArrayInitialize(m_lpszBuffer, 64);
|
|
|
|
//
|
|
m_nCount[0] = m_nCount[1] = 0;
|
|
m_lMD5[0] = _md5_INIT_STATE_0;
|
|
m_lMD5[1] = _md5_INIT_STATE_1;
|
|
m_lMD5[2] = _md5_INIT_STATE_2;
|
|
m_lMD5[3] = _md5_INIT_STATE_3;
|
|
}
|
|
|
|
//
|
|
// Update MD5 ...
|
|
void MD5Update(uchar &inBuf[], uint inLen)
|
|
{
|
|
//
|
|
int i, ii;
|
|
int mdi;
|
|
|
|
//
|
|
uint in[16];
|
|
int i0 = 0;
|
|
|
|
//
|
|
mdi = (int)((m_nCount[0] >> 3) & 0x3F);
|
|
|
|
//
|
|
if ((m_nCount[0] + ((uint)inLen << 3)) < m_nCount[0])
|
|
{
|
|
m_nCount[1]++;
|
|
}
|
|
|
|
//
|
|
m_nCount[0] += ((uint)inLen << 3);
|
|
m_nCount[1] += ((uint)inLen >> 29);
|
|
|
|
//
|
|
while ((inLen--) > 0)
|
|
{
|
|
//
|
|
m_lpszBuffer[mdi++] = inBuf[i0++];
|
|
if (mdi == 0x40)
|
|
{
|
|
//
|
|
for (i = 0, ii = 0; i < 16; i++, ii += 4)
|
|
{
|
|
in[i] = (((uint)m_lpszBuffer[ii + 3]) << 24) | (((uint)m_lpszBuffer[ii + 2]) << 16) | (((uint)m_lpszBuffer[ii + 1]) << 8) | ((uint)m_lpszBuffer[ii]);
|
|
}
|
|
|
|
//
|
|
Transform(m_lMD5, in);
|
|
|
|
//
|
|
mdi = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Finalize an MD5 Expression ...
|
|
string MD5Final()
|
|
{
|
|
//
|
|
uchar bits[8];
|
|
int nIndex;
|
|
uint nPadLen;
|
|
const int nMD5Size = 16;
|
|
uchar lpszMD5[16];
|
|
string temp;
|
|
string out = "";
|
|
int i;
|
|
|
|
//
|
|
DWordToByte(bits, m_nCount, 8);
|
|
nIndex = (int)((m_nCount[0] >> 3) & 0x3f);
|
|
nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex);
|
|
MD5Update(_md5_PADDING, nPadLen);
|
|
MD5Update(bits, 8);
|
|
DWordToByte(lpszMD5, m_lMD5, nMD5Size);
|
|
|
|
//
|
|
for (i = 0; i < nMD5Size; i++)
|
|
{
|
|
//
|
|
if (lpszMD5[i] == 0)
|
|
{
|
|
temp = "00";
|
|
}
|
|
else if (lpszMD5[i] <= 15)
|
|
{
|
|
temp = StringFormat("0%x", lpszMD5[i]);
|
|
}
|
|
else
|
|
{
|
|
temp = StringFormat("%x", lpszMD5[i]);
|
|
}
|
|
|
|
//
|
|
out += temp;
|
|
}
|
|
|
|
//
|
|
lpszMD5[0] = '\0';
|
|
|
|
//
|
|
return (out);
|
|
}
|
|
|
|
//
|
|
// Transform Buffers ...
|
|
void Transform(uint &buf[], uint &in[])
|
|
{
|
|
//
|
|
uint a = buf[0], b = buf[1], c = buf[2], d = buf[3];
|
|
|
|
//
|
|
_md5_FF(a, b, c, d, in[0], _md5_S11, 0xD76AA478);
|
|
_md5_FF(d, a, b, c, in[1], _md5_S12, 0xE8C7B756);
|
|
_md5_FF(c, d, a, b, in[2], _md5_S13, 0x242070DB);
|
|
_md5_FF(b, c, d, a, in[3], _md5_S14, 0xC1BDCEEE);
|
|
_md5_FF(a, b, c, d, in[4], _md5_S11, 0xF57C0FAF);
|
|
_md5_FF(d, a, b, c, in[5], _md5_S12, 0x4787C62A);
|
|
_md5_FF(c, d, a, b, in[6], _md5_S13, 0xA8304613);
|
|
_md5_FF(b, c, d, a, in[7], _md5_S14, 0xFD469501);
|
|
_md5_FF(a, b, c, d, in[8], _md5_S11, 0x698098D8);
|
|
_md5_FF(d, a, b, c, in[9], _md5_S12, 0x8B44F7AF);
|
|
_md5_FF(c, d, a, b, in[10], _md5_S13, 0xFFFF5BB1);
|
|
_md5_FF(b, c, d, a, in[11], _md5_S14, 0x895CD7BE);
|
|
_md5_FF(a, b, c, d, in[12], _md5_S11, 0x6B901122);
|
|
_md5_FF(d, a, b, c, in[13], _md5_S12, 0xFD987193);
|
|
_md5_FF(c, d, a, b, in[14], _md5_S13, 0xA679438E);
|
|
_md5_FF(b, c, d, a, in[15], _md5_S14, 0x49B40821);
|
|
|
|
//
|
|
_md5_GG(a, b, c, d, in[1], _md5_S21, 0xF61E2562);
|
|
_md5_GG(d, a, b, c, in[6], _md5_S22, 0xC040B340);
|
|
_md5_GG(c, d, a, b, in[11], _md5_S23, 0x265E5A51);
|
|
_md5_GG(b, c, d, a, in[0], _md5_S24, 0xE9B6C7AA);
|
|
_md5_GG(a, b, c, d, in[5], _md5_S21, 0xD62F105D);
|
|
_md5_GG(d, a, b, c, in[10], _md5_S22, 0x02441453);
|
|
_md5_GG(c, d, a, b, in[15], _md5_S23, 0xD8A1E681);
|
|
_md5_GG(b, c, d, a, in[4], _md5_S24, 0xE7D3FBC8);
|
|
_md5_GG(a, b, c, d, in[9], _md5_S21, 0x21E1CDE6);
|
|
_md5_GG(d, a, b, c, in[14], _md5_S22, 0xC33707D6);
|
|
_md5_GG(c, d, a, b, in[3], _md5_S23, 0xF4D50D87);
|
|
_md5_GG(b, c, d, a, in[8], _md5_S24, 0x455A14ED);
|
|
_md5_GG(a, b, c, d, in[13], _md5_S21, 0xA9E3E905);
|
|
_md5_GG(d, a, b, c, in[2], _md5_S22, 0xFCEFA3F8);
|
|
_md5_GG(c, d, a, b, in[7], _md5_S23, 0x676F02D9);
|
|
_md5_GG(b, c, d, a, in[12], _md5_S24, 0x8D2A4C8A);
|
|
|
|
//
|
|
_md5_HH(a, b, c, d, in[5], _md5_S31, 0xFFFA3942);
|
|
_md5_HH(d, a, b, c, in[8], _md5_S32, 0x8771F681);
|
|
_md5_HH(c, d, a, b, in[11], _md5_S33, 0x6D9D6122);
|
|
_md5_HH(b, c, d, a, in[14], _md5_S34, 0xFDE5380C);
|
|
_md5_HH(a, b, c, d, in[1], _md5_S31, 0xA4BEEA44);
|
|
_md5_HH(d, a, b, c, in[4], _md5_S32, 0x4BDECFA9);
|
|
_md5_HH(c, d, a, b, in[7], _md5_S33, 0xF6BB4B60);
|
|
_md5_HH(b, c, d, a, in[10], _md5_S34, 0xBEBFBC70);
|
|
_md5_HH(a, b, c, d, in[13], _md5_S31, 0x289B7EC6);
|
|
_md5_HH(d, a, b, c, in[0], _md5_S32, 0xEAA127FA);
|
|
_md5_HH(c, d, a, b, in[3], _md5_S33, 0xD4EF3085);
|
|
_md5_HH(b, c, d, a, in[6], _md5_S34, 0x04881D05);
|
|
_md5_HH(a, b, c, d, in[9], _md5_S31, 0xD9D4D039);
|
|
_md5_HH(d, a, b, c, in[12], _md5_S32, 0xE6DB99E5);
|
|
_md5_HH(c, d, a, b, in[15], _md5_S33, 0x1FA27CF8);
|
|
_md5_HH(b, c, d, a, in[2], _md5_S34, 0xC4AC5665);
|
|
|
|
//
|
|
_md5_II(a, b, c, d, in[0], _md5_S41, 0xF4292244);
|
|
_md5_II(d, a, b, c, in[7], _md5_S42, 0x432AFF97);
|
|
_md5_II(c, d, a, b, in[14], _md5_S43, 0xAB9423A7);
|
|
_md5_II(b, c, d, a, in[5], _md5_S44, 0xFC93A039);
|
|
_md5_II(a, b, c, d, in[12], _md5_S41, 0x655B59C3);
|
|
_md5_II(d, a, b, c, in[3], _md5_S42, 0x8F0CCC92);
|
|
_md5_II(c, d, a, b, in[10], _md5_S43, 0xFFEFF47D);
|
|
_md5_II(b, c, d, a, in[1], _md5_S44, 0x85845DD1);
|
|
_md5_II(a, b, c, d, in[8], _md5_S41, 0x6FA87E4F);
|
|
_md5_II(d, a, b, c, in[15], _md5_S42, 0xFE2CE6E0);
|
|
_md5_II(c, d, a, b, in[6], _md5_S43, 0xA3014314);
|
|
_md5_II(b, c, d, a, in[13], _md5_S44, 0x4E0811A1);
|
|
_md5_II(a, b, c, d, in[4], _md5_S41, 0xF7537E82);
|
|
_md5_II(d, a, b, c, in[11], _md5_S42, 0xBD3AF235);
|
|
_md5_II(c, d, a, b, in[2], _md5_S43, 0x2AD7D2BB);
|
|
_md5_II(b, c, d, a, in[9], _md5_S44, 0xEB86D391);
|
|
|
|
//
|
|
buf[0] += a;
|
|
buf[1] += b;
|
|
buf[2] += c;
|
|
buf[3] += d;
|
|
}
|
|
};
|