rcpp_framework/core/ssl_funcs/Md5.cc

352 lines
9.0 KiB
C++

/**
*
* Md5.cc
* An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* Drogon
*
*/
#include "Md5.h"
#include <math.h>
#include <string.h>
const uint32_t Md5Encode::kA = 0x67452301;
const uint32_t Md5Encode::kB = 0xefcdab89;
const uint32_t Md5Encode::kC = 0x98badcfe;
const uint32_t Md5Encode::kD = 0x10325476;
const uint64_t Md5Encode::tiNumInteger = 4294967296;
// function: CycleMoveLeft
// @param srcNum: the number to be moved left
// @param bitNumToMove: the number of bit of moving
// @return result after moving
uint32_t Md5Encode::cycleMoveLeft(uint32_t srcNum, int bitNumToMove)
{
uint32_t srcNum1 = srcNum;
uint32_t srcNum2 = srcNum;
if (0 >= bitNumToMove)
{
return srcNum;
}
return ((srcNum1 << bitNumToMove) | (srcNum2 >> (32 - bitNumToMove)));
}
// function: FillData
// @param inDataPtr: input data
// @param dataByteLen: length of input data
// @param outDataPtr: output data
// return : length of output data
uint32_t Md5Encode::fillData(const char *inDataPtr,
int dataByteLen,
char **outDataPtr)
{
int bitNum = dataByteLen * BIT_OF_BYTE;
// int grop_num = bitNum / BIT_OF_GROUP;
int modBitNum = bitNum % BIT_OF_GROUP;
int bitNeedFill = 0;
if (modBitNum > (BIT_OF_GROUP - SRC_DATA_LEN))
{
bitNeedFill = (BIT_OF_GROUP - modBitNum);
bitNeedFill += (BIT_OF_GROUP - SRC_DATA_LEN);
}
else
{
bitNeedFill = (BIT_OF_GROUP - SRC_DATA_LEN) - modBitNum;
}
int allBit = bitNum + bitNeedFill;
if (0 < bitNeedFill)
{
*outDataPtr =
new char[allBit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE];
memset(*outDataPtr,
0,
allBit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE);
// copy data
memcpy(*outDataPtr, inDataPtr, dataByteLen);
// fill rest data
unsigned char *tmp = reinterpret_cast<unsigned char *>(*outDataPtr);
tmp += dataByteLen;
// fill 1 and 0
*tmp = 0x80;
// fill origin data len
unsigned long long *originNum =
(unsigned long long *)((*outDataPtr) + ((allBit / BIT_OF_BYTE)));
*originNum = dataByteLen * BIT_OF_BYTE;
}
return (allBit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE);
}
void Md5Encode::roundF(char *data512Ptr, ParamDynamic &param)
{
uint32_t *M = reinterpret_cast<uint32_t *>(data512Ptr);
int s[] = {7, 12, 17, 22};
for (int i = 0; i < 16; ++i)
{
uint64_t ti = tiNumInteger * fabs(sin(i + 1));
if (i % 4 == 0)
{
FF(param.ua_, param.ub_, param.uc_, param.ud_, M[i], s[i % 4], ti);
}
else if (i % 4 == 1)
{
FF(param.ud_, param.ua_, param.ub_, param.uc_, M[i], s[i % 4], ti);
}
else if (i % 4 == 2)
{
FF(param.uc_, param.ud_, param.ua_, param.ub_, M[i], s[i % 4], ti);
}
else if (i % 4 == 3)
{
FF(param.ub_, param.uc_, param.ud_, param.ua_, M[i], s[i % 4], ti);
}
}
}
void Md5Encode::roundG(char *data512Ptr, ParamDynamic &param)
{
uint32_t *M = reinterpret_cast<uint32_t *>(data512Ptr);
int s[] = {5, 9, 14, 20};
for (int i = 0; i < 16; ++i)
{
auto sss = sin(i + 1 + 16);
uint64_t ti = tiNumInteger * fabs(sss);
int index = (i * 5 + 1) % 16;
if (i % 4 == 0)
{
GG(param.ua_,
param.ub_,
param.uc_,
param.ud_,
M[index],
s[i % 4],
ti);
}
else if (i % 4 == 1)
{
GG(param.ud_,
param.ua_,
param.ub_,
param.uc_,
M[index],
s[i % 4],
ti);
}
else if (i % 4 == 2)
{
GG(param.uc_,
param.ud_,
param.ua_,
param.ub_,
M[index],
s[i % 4],
ti);
}
else if (i % 4 == 3)
{
GG(param.ub_,
param.uc_,
param.ud_,
param.ua_,
M[index],
s[i % 4],
ti);
}
}
}
void Md5Encode::roundH(char *data512Ptr, ParamDynamic &param)
{
uint32_t *M = reinterpret_cast<uint32_t *>(data512Ptr);
int s[] = {4, 11, 16, 23};
for (int i = 0; i < 16; ++i)
{
uint64_t ti = tiNumInteger * fabs(sin(i + 1 + 32));
int index = (i * 3 + 5) % 16;
if (i % 4 == 0)
{
HH(param.ua_,
param.ub_,
param.uc_,
param.ud_,
M[index],
s[i % 4],
ti);
}
else if (i % 4 == 1)
{
HH(param.ud_,
param.ua_,
param.ub_,
param.uc_,
M[index],
s[i % 4],
ti);
}
else if (i % 4 == 2)
{
HH(param.uc_,
param.ud_,
param.ua_,
param.ub_,
M[index],
s[i % 4],
ti);
}
else if (i % 4 == 3)
{
HH(param.ub_,
param.uc_,
param.ud_,
param.ua_,
M[index],
s[i % 4],
ti);
}
}
}
void Md5Encode::roundI(char *data512Ptr, ParamDynamic &param)
{
uint32_t *M = reinterpret_cast<uint32_t *>(data512Ptr);
int s[] = {6, 10, 15, 21};
for (int i = 0; i < 16; ++i)
{
uint64_t ti = tiNumInteger * fabs(sin(i + 1 + 48));
int index = (i * 7 + 0) % 16;
if (i % 4 == 0)
{
II(param.ua_,
param.ub_,
param.uc_,
param.ud_,
M[index],
s[i % 4],
ti);
}
else if (i % 4 == 1)
{
II(param.ud_,
param.ua_,
param.ub_,
param.uc_,
M[index],
s[i % 4],
ti);
}
else if (i % 4 == 2)
{
II(param.uc_,
param.ud_,
param.ua_,
param.ub_,
M[index],
s[i % 4],
ti);
}
else if (i % 4 == 3)
{
II(param.ub_,
param.uc_,
param.ud_,
param.ua_,
M[index],
s[i % 4],
ti);
}
}
}
void Md5Encode::rotationCalculate(char *data512Ptr, ParamDynamic &param)
{
if (nullptr == data512Ptr)
{
return;
}
roundF(data512Ptr, param);
roundG(data512Ptr, param);
roundH(data512Ptr, param);
roundI(data512Ptr, param);
param.ua_ = param.va_last_ + param.ua_;
param.ub_ = param.vb_last_ + param.ub_;
param.uc_ = param.vc_last_ + param.uc_;
param.ud_ = param.vd_last_ + param.ud_;
param.va_last_ = param.ua_;
param.vb_last_ = param.ub_;
param.vc_last_ = param.uc_;
param.vd_last_ = param.ud_;
}
// Convert to hex format string
std::string Md5Encode::getHexStr(uint32_t numStr)
{
std::string hexstr = "";
char szch[] = {'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F'};
unsigned char *tmptr = (unsigned char *)&numStr;
int len = sizeof(numStr);
for (int i = 0; i < len; ++i)
{
unsigned char ch = tmptr[i] & 0xF0;
ch = ch >> 4;
hexstr.append(1, szch[ch]);
ch = tmptr[i] & 0x0F;
hexstr.append(1, szch[ch]);
}
return hexstr;
}
// function: Encode
// @param srcInfo: the string to be encoded.
// return : the string after encoding
std::string Md5Encode::encode(const char *data, const size_t dataLen)
{
ParamDynamic param;
param.ua_ = kA;
param.ub_ = kB;
param.uc_ = kC;
param.ud_ = kD;
param.va_last_ = kA;
param.vb_last_ = kB;
param.vc_last_ = kC;
param.vd_last_ = kD;
std::string result;
char *outDataPtr = nullptr;
int totalByte = fillData(data, dataLen, &outDataPtr);
for (int i = 0; i < totalByte / (BIT_OF_GROUP / BIT_OF_BYTE); ++i)
{
char *dataBitOfGroup = outDataPtr;
dataBitOfGroup += i * (BIT_OF_GROUP / BIT_OF_BYTE);
rotationCalculate(dataBitOfGroup, param);
}
delete[] outDataPtr, outDataPtr = nullptr;
result.append(getHexStr(param.ua_));
result.append(getHexStr(param.ub_));
result.append(getHexStr(param.uc_));
result.append(getHexStr(param.ud_));
return result;
}