Just a homework. NOT for production environment.
#include "md5.h"
#include <iostream>
using std::cout;
using std::endl;
void simple() {
MD5 md5("string to md5");
auto res = md5.digest().getHexResult();
cout << res << endl;
}
void useUpdate() {
MD5 md5;
md5.update("string");
md5.update(" to ").update("update").digest();
auto res = md5.getHexResult();
cout << res << endl;
}
void readFile() {
MD5 md5;
md5.update("path_to_file", MD5::UPDATE_TYPE::UPDATE_FILE);
auto res = md5.digest().getHexResult();
cout << res << endl;
}
Reference: RFC 1321 and my teacher's courseware
Step 1 (Append Padding) and Step 2 (Append Length) in RFC 1321 can be delayed, and Step 3 (Intialize MD Buffer) can be done in the class's initialize time. So, this implementation first proceeds Step 4 (Process Message in 16-Word Blocks) except the final block. (Step 1 and 2 are only applied on the final block)
When callling update()
, the new data will be appended to the buffer -- which carrys the final block of the last update()
. This means m1
and m2
are the same in the following code.
MD5 m1, m2;
m1.update("123456").digest();
m2.update("123").update("456").digest();
As for the private method process()
, it will process the current buffer
. It won't clear the buffer
, it is update()
's work to update buffer and call process()
.
Files won't be fully read by one reading operation, which means this implementation won't use too much memory. (Depends on the constexpr
in md5.h called FILE_READ_BLOCK_SIZE
)
More explanations on the code are in the code comment block.
Part of the test suite can be found in RFC 1321, others are generated by python's hashlib
library. (Yes, I trust it to be a correct implementation!)
Check the file md5_test.cpp !