Files
Sun1602/Client/FrostShieldLib/md5.cpp
T
2022-10-26 12:25:11 +08:00

234 lines
6.6 KiB
C++

#include "md5.h"
#include "converter.h"
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include <fstream>
#include <sstream>
extern std::ofstream frostLogFile;
extern bool frostLogging;
namespace utils {
const char md5Hash::m_oneAndZeros = (char)0x80;
const char md5Hash::m_zeros = (char)0x0;
const unsigned md5Hash::m_bufLen = 8192;
const unsigned __int32 md5Hash::m_k[64] = {
3614090360, 3905402710, 606105819, 3250441966,
4118548399, 1200080426, 2821735955, 4249261313,
1770035416, 2336552879, 4294925233, 2304563134,
1804603682, 4254626195, 2792965006, 1236535329,
4129170786, 3225465664, 643717713, 3921069994,
3593408605, 38016083, 3634488961, 3889429448,
568446438, 3275163606, 4107603335, 1163531501,
2850285829, 4243563512, 1735328473, 2368359562,
4294588738, 2272392833, 1839030562, 4259657740,
2763975236, 1272893353, 4139469664, 3200236656,
681279174, 3936430074, 3572445317, 76029189,
3654602809, 3873151461, 530742520, 3299628645,
4096336452, 1126891415, 2878612391, 4237533241,
1700485571, 2399980690, 4293915773, 2240044497,
1873313359, 4264355552, 2734768916, 1309151649,
4149444226, 3174756917, 718787259, 3951481745
};
const unsigned __int32 md5Hash::m_r[64] = {
7, 12, 17, 22, 7, 12, 17, 22,
7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20,
5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23,
4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21,
6, 10, 15, 21, 6, 10, 15, 21
};
md5Hash::md5Hash()
{
m_buff = new char[m_bufLen];
}
md5Hash::~md5Hash()
{
delete[] m_buff;
}
std::wstring md5Hash::get_random_crc()
{
if(frostLogging) {
frostLogFile << "md5Hash::get_random_crc()" << std::endl;
}
static bool b = false;
if(!b) {
b = true;
srand((unsigned)time(0));
}
std::string crc = int2hexstr(rand());
crc += int2hexstr(time(0));
crc += int2hexstr(rand());
while(crc.size() < 32) {
crc += (char)((rand() % 26) + 'a');
}
if(frostLogging) {
frostLogFile << "md5Hash::get_random_crc() = " << crc << std::endl;
}
return ascii_to_utf16(crc.c_str());
}
std::wstring md5Hash::getMD5FromFile(const wchar_t* fileName,
OnMD5Progress_t clb,
void* userData,
double alpha,
bool* running)
{
if(frostLogging) {
frostLogFile << "md5Hash::getMD5FromFile(" << utf16_to_ascii(fileName ? fileName : L"NULL") << ")" << std::endl;
}
m_h[0] = 0x67452301;
m_h[1] = 0xEFCDAB89;
m_h[2] = 0x98BADCFE;
m_h[3] = 0x10325476;
__int64 bitLen = 0;
unsigned char res[16] = {0};
char* part;//[0x40] = {0};
__int64 i = 0;
unsigned __int64 pIteration = 0, pIterationDelta = 10000000;
FILE* myFile = _wfopen(fileName, L"rb");
if(myFile) {
size_t fromFile = 0;
while (true) {
if(running && !(*running)) break;
if(!fromFile) {
fromFile = fread(m_buff, 1, m_bufLen, myFile);
part = m_buff;
}
size_t gcount = fromFile > 0x40 ? 0x40 : fromFile;
pIteration += gcount;
if(pIterationDelta <= pIteration) {
if(clb) {
clb((unsigned)pIteration, userData, alpha);
}
pIteration = 0;
}
if (gcount == 64) {
bitLen += gcount * 8;
processChunk(part);
} else {
bitLen += gcount * 8;
i = gcount;
part[i] = m_oneAndZeros;
++i;
if (i > 0x38) {
for (int j = (int)i; j < 0x40; ++j){
part[j] = m_zeros;
}
i = 0;
processChunk(part);
}
for (int j = (int)i; j < 0x40; ++j) {
if (j < 0x38) {
part[j] = m_zeros;
} else {
part[j] = (char)(bitLen >> (8 * (j - 0x38)));
}
}
processChunk(part);
break;
}
part += gcount;
fromFile -= gcount;
}
fclose(myFile);
for (int i = 0; i < 16; i++) {
res[i] = ((char*)&m_h[i / 4])[(i % 4)];
}
if(pIteration) {
if(clb) {
clb((unsigned)pIteration, userData, alpha);
}
}
if(frostLogging) {
frostLogFile << "md5Hash::getMD5FromFile() = ok" << std::endl;
}
return convToString(res);
}
if(frostLogging) {
frostLogFile << "md5Hash::getMD5FromFile() = fail" << std::endl;
}
return L"";
}
void md5Hash::processChunk(char input[64])
{
unsigned __int32 a = m_h[0];
unsigned __int32 b = m_h[1];
unsigned __int32 c = m_h[2];
unsigned __int32 d = m_h[3];
unsigned __int32 t = 0;
unsigned __int32 f = 0;
unsigned __int32 g = 0;
unsigned __int32 w0 = 0;
unsigned __int32 w1 = 0;
unsigned __int32 w2 = 0;
unsigned __int32 w3 = 0;
unsigned __int32 w[16] = {0};
for (int i = 0; i < 64; ++i) {
if (i < 16) {
w0 = (int)input[4 * i + 0];
w1 = (int)input[4 * i + 1];
w2 = (int)input[4 * i + 2];
w3 = (int)input[4 * i + 3];
w[i] = (w0 & 0x000000FF) | ((w1 << 8) & 0x0000FF00) | ((w2 << 16) & 0x00FF0000) | ((w3 << 24) & 0xFF000000);
f = F(b, c, d);
g = i;
} else if (i < 32) {
f = G(b, c, d);
g = (5 * i + 1) % 16;
} else if (i < 48) {
f = H(b, c, d);
g = (3 * i + 5) % 16;
} else {
f = I(b, c, d);
g = (7 * i) % 16;
}
t = d;
d = c;
c = b;
b = b + ROTATE_LEFT((a + f + m_k[i] + w[g]) , m_r[i]);
a = t;
}
m_h[0] += a;
m_h[1] += b;
m_h[2] += c;
m_h[3] += d;
}
std::wstring md5Hash::convToString(unsigned char* bytes)
{
std::ostringstream os;
for(int i = 0; i < 16; i++) {
os.width(2);
os.fill('0');
os << std::hex << (0xff & static_cast<unsigned int>(bytes[i]));
}
return ascii_to_utf16(os.str().c_str());
}
void md5Hash::convToString(unsigned char* bytes, char* md5Buff)
{
std::stringstream os;
for(int i = 0; i < 16; i++) {
os.width(2);
os.fill('0');
os << std::hex << (0xff & static_cast<unsigned int>(bytes[i]));
}
os >> md5Buff;
}
}