我正在使用C++中的程序來執行md5校驗和。我這樣做主要是因爲我認爲我會學習關於C++,校驗和,OOP以及其他任何我遇到的很多不同的事情。我如何使用c/C++來填充我的md5消息
我有麻煩檢查總和,我認爲問題是在功能padbuff做消息填充。
#include "HashMD5.h"
int leftrotate(int x, int y);
void padbuff(uchar * buffer);
//HashMD5 constructor
HashMD5::HashMD5()
{
Type = "md5";
Hash = "";
}
HashMD5::HashMD5(const char * hashfile)
{
Type = "md5";
std::ifstream filestr;
filestr.open(hashfile, std::fstream::in | std::fstream::binary);
if(filestr.fail())
{
std::cerr << "File " << hashfile << " was not opened.\n";
std::cerr << "Open failed with error ";
}
}
std::string HashMD5::GetType()
{
return this->Type;
}
std::string HashMD5::GetHash()
{
return this->Hash;
}
bool HashMD5::is_open()
{
return !((this->filestr).fail());
}
void HashMD5::CalcHash(unsigned int * hash)
{
unsigned int *r, *k;
int r2[4] = {0, 4, 9, 15};
int r3[4] = {0, 7, 12, 19};
int r4[4] = {0, 4, 9, 15};
uchar * buffer;
int bufLength = (2<<20)*8;
int f,g,a,b,c,d, temp;
int *head;
uint32_t maxint = 1<<31;
//Initialized states
unsigned int h[4]{ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476};
r = new unsigned int[64];
k = new unsigned int[64];
buffer = new uchar[bufLength];
if(r==NULL || k==NULL || buffer==NULL)
{
std::cerr << "One of the dyn alloc failed\n";
}
// r specifies the per-round shift amounts
for(int i = 0; i<16; i++)
r[i] = 7 + (5 * ((i)%4));
for(int i = 16; i < 32; i++)
r[i] = 5 + r2[i%4];
for(int i = 32; i< 48; i++)
r[i] = 4 + r3[i%4];
for(int i = 48; i < 63; i++)
r[i] = 6 + r4[i%4];
for(int i = 0; i < 63; i++)
{
k[i] = floor(fabs(sin(i + 1)) * maxint);
}
while(!(this->filestr).eof())
{
//Read in 512 bits
(this->filestr).read((char *)buffer, bufLength-512);
padbuff(buffer);
//The 512 bits are now 16 32-bit ints
head = (int *)buffer;
for(int i = 0; i < 64; i++)
{
if(i >=0 && i <=15)
{
f = (b & c) | (~b & d);
g = i;
}
else if(i >= 16 && i <=31)
{
f = (d & b) | (~d & b);
g = (5*i +1) % 16;
}
else if(i >=32 && i<=47)
{
f = b^c^d;
g = (3*i + 5) % 16;
}
else
{
f = c^(b | ~d);
g = (7*i) % 16;
}
temp = d;
d = c;
c = b;
b = b + leftrotate((a + f + k[i] + head[g]), r[i]);
a = temp;
}
h[0] +=a;
h[1] +=b;
h[2] +=c;
h[3] +=d;
}
delete[] r;
delete[] k;
hash = h;
}
int leftrotate(int x, int y)
{
return(x<<y) | (x >> (32 -y));
}
void padbuff(uchar* buffer)
{
int lack;
int length = strlen((char *)buffer);
uint64_t mes_size = length % UINT64_MAX;
if((lack = (112 - (length % 128)))>0)
{
*(buffer + length) = ('\0'+1) << 3;
memset((buffer + length + 1),0x0,lack);
memcpy((void*)(buffer+112),(void *)&mes_size, 64);
}
}
在我的測試程序中,我在一條空的消息上運行它。因此,在padbuff中的length
爲0.然後,當我做*(buffer + length) = ('\0'+1) << 3;
時,我試圖用1填充消息。在Netbeans調試器中,我將buffer
作爲uint64_t
並且它說buffer=8
。我試圖把1 bit
放在最重要的緩衝區,所以我的演員應該是UINT64_MAX
。它不是,所以我很困惑我的填充代碼如何工作。有人能告訴我我在做什麼以及我應該在padbuff中做什麼嗎?謝謝,我對這個漫長的問題表示歉意。
只是爲了清楚填充應該做什麼,這裏是來自Wikipedia的填充摘錄: 消息被填充以使其長度可以被512整除。填充的工作原理如下:首先一個位,1被添加到消息的末尾。接着是所需要的零,以使消息的長度多達64位,少於512的倍數。其餘位填充64位,表示原始消息的長度,模264。
我主要是在尋找padbuff的幫助,但是因爲我正在努力學習所有的評論都很感謝。