Skip to content

Instantly share code, notes, and snippets.

@thevar1able
Created January 15, 2016 12:29
Show Gist options
  • Select an option

  • Save thevar1able/5ffa68f0b0bcaed07da7 to your computer and use it in GitHub Desktop.

Select an option

Save thevar1able/5ffa68f0b0bcaed07da7 to your computer and use it in GitHub Desktop.
simple md5 implementation
#include <iostream>
#include <stdint.h>
#include <bitset>
#include <cmath>
#include <vector>
#include <fstream>
#include <sstream>
#include <string>
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
using namespace std;
inline uint32_t rotate_left(uint32_t val, int n) {
return (val << n) | ((val & 0xffffffff) >> (32-n));
}
std::string rawMD5toString(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
std::stringstream ss;
ss << hex << __bswap_32(a) << __bswap_32(b) << __bswap_32(c) << __bswap_32(d);
return ss.str();
}
std::string countMD5(std::vector<uint32_t> buffer){
uint32_t A = 0x67452301;
uint32_t B = 0xefcdab89;
uint32_t C = 0x98badcfe;
uint32_t D = 0x10325476;
uint32_t T[65];
for (uint8_t i = 1; i <= 65; ++i) {
double t;
t = trunc(pow(2, 32) * abs(sin(i)));
T[i] = (uint32_t)t;
}
for (int i = 0; i < buffer.size() / 16; ++i) {
uint32_t X[16];
for (int j = 0; j < 16; ++j) {
X[j] = buffer[i * 16 + j];
}
uint32_t AA = A;
uint32_t BB = B;
uint32_t CC = C;
uint32_t DD = D;
/* 1 */
A = B + (rotate_left((A + F(B, C, D) + X[0] + T[1]), 7));
D = A + (rotate_left((D + F(A, B, C) + X[1] + T[2]), 12));
C = D + (rotate_left((C + F(D, A, B) + X[2] + T[3]), 17));
B = C + (rotate_left((B + F(C, D, A) + X[3] + T[4]), 22));
A = B + (rotate_left((A + F(B, C, D) + X[4] + T[5]), 7));
D = A + (rotate_left((D + F(A, B, C) + X[5] + T[6]), 12));
C = D + (rotate_left((C + F(D, A, B) + X[6] + T[7]), 17));
B = C + (rotate_left((B + F(C, D, A) + X[7] + T[8]), 22));
A = B + (rotate_left((A + F(B, C, D) + X[8] + T[9]), 7));
D = A + (rotate_left((D + F(A, B, C) + X[9] + T[10]), 12));
C = D + (rotate_left((C + F(D, A, B) + X[10] + T[11]), 17));
B = C + (rotate_left((B + F(C, D, A) + X[11] + T[12]), 22));
A = B + (rotate_left((A + F(B, C, D) + X[12] + T[13]), 7));
D = A + (rotate_left((D + F(A, B, C) + X[13] + T[14]), 12));
C = D + (rotate_left((C + F(D, A, B) + X[14] + T[15]), 17));
B = C + (rotate_left((B + F(C, D, A) + X[15] + T[16]), 22));
// std::cout<<hex<<A << B << C << D << endl;
/* !1 */
/* 2 */
A = B + (rotate_left((A + G(B, C, D) + X[1] + T[17]), 5));
D = A + (rotate_left((D + G(A, B, C) + X[6] + T[18]), 9));
C = D + (rotate_left((C + G(D, A, B) + X[11] + T[19]), 14));
B = C + (rotate_left((B + G(C, D, A) + X[0] + T[20]), 20));
A = B + (rotate_left((A + G(B, C, D) + X[5] + T[21]), 5));
D = A + (rotate_left((D + G(A, B, C) + X[10] + T[22]), 9));
C = D + (rotate_left((C + G(D, A, B) + X[15] + T[23]), 14));
B = C + (rotate_left((B + G(C, D, A) + X[4] + T[24]), 20));
A = B + (rotate_left((A + G(B, C, D) + X[9] + T[25]), 5));
D = A + (rotate_left((D + G(A, B, C) + X[14] + T[26]), 9));
C = D + (rotate_left((C + G(D, A, B) + X[3] + T[27]), 14));
B = C + (rotate_left((B + G(C, D, A) + X[8] + T[28]), 20));
A = B + (rotate_left((A + G(B, C, D) + X[13] + T[29]), 5));
D = A + (rotate_left((D + G(A, B, C) + X[2] + T[30]), 9));
C = D + (rotate_left((C + G(D, A, B) + X[7] + T[31]), 14));
B = C + (rotate_left((B + G(C, D, A) + X[12] + T[32]), 20));
/* !2 */
/* 3 */
A = B + (rotate_left((A + H(B, C, D) + X[5] + T[33]), 4));
D = A + (rotate_left((D + H(A, B, C) + X[8] + T[34]), 11));
C = D + (rotate_left((C + H(D, A, B) + X[11] + T[35]), 16));
B = C + (rotate_left((B + H(C, D, A) + X[14] + T[36]), 23));
A = B + (rotate_left((A + H(B, C, D) + X[1] + T[37]), 4));
D = A + (rotate_left((D + H(A, B, C) + X[4] + T[38]), 11));
C = D + (rotate_left((C + H(D, A, B) + X[7] + T[39]), 16));
B = C + (rotate_left((B + H(C, D, A) + X[10] + T[40]), 23));
A = B + (rotate_left((A + H(B, C, D) + X[13] + T[41]), 4));
D = A + (rotate_left((D + H(A, B, C) + X[0] + T[42]), 11));
C = D + (rotate_left((C + H(D, A, B) + X[3] + T[43]), 16));
B = C + (rotate_left((B + H(C, D, A) + X[6] + T[44]), 23));
A = B + (rotate_left((A + H(B, C, D) + X[9] + T[45]), 4));
D = A + (rotate_left((D + H(A, B, C) + X[12] + T[46]), 11));
C = D + (rotate_left((C + H(D, A, B) + X[15] + T[47]), 16));
B = C + (rotate_left((B + H(C, D, A) + X[2] + T[48]), 23));
/* !3 */
/* 4 */
A = B + (rotate_left((A + I(B, C, D) + X[0] + T[49]), 6));
D = A + (rotate_left((D + I(A, B, C) + X[7] + T[50]), 10));
C = D + (rotate_left((C + I(D, A, B) + X[14] + T[51]), 15));
B = C + (rotate_left((B + I(C, D, A) + X[5] + T[52]), 21));
A = B + (rotate_left((A + I(B, C, D) + X[12] + T[53]), 6));
D = A + (rotate_left((D + I(A, B, C) + X[3] + T[54]), 10));
C = D + (rotate_left((C + I(D, A, B) + X[10] + T[55]), 15));
B = C + (rotate_left((B + I(C, D, A) + X[1] + T[56]), 21));
A = B + (rotate_left((A + I(B, C, D) + X[8] + T[57]), 6));
D = A + (rotate_left((D + I(A, B, C) + X[15] + T[58]), 10));
C = D + (rotate_left((C + I(D, A, B) + X[6] + T[59]), 15));
B = C + (rotate_left((B + I(C, D, A) + X[13] + T[60]), 21));
A = B + (rotate_left((A + I(B, C, D) + X[4] + T[61]), 6));
D = A + (rotate_left((D + I(A, B, C) + X[11] + T[62]), 10));
C = D + (rotate_left((C + I(D, A, B) + X[2] + T[63]), 15));
B = C + (rotate_left((B + I(C, D, A) + X[9] + T[64]), 21));
/* !4 */
A += AA;
B += BB;
C += CC;
D += DD;
}
return rawMD5toString(A, B, C, D);
// std::cout << std::hex << __bswap_32(A) << __bswap_32(B) << __bswap_32(C) << __bswap_32(D);
}
std::vector<char> readFile(char* filename) {
ifstream ifs(filename, ios::binary|ios::ate);
ifstream::pos_type pos = ifs.tellg();
std::vector<char> result(pos);
ifs.seekg(0, ios::beg);
ifs.read(&result[0], pos);
return result;
}
std::vector<char> prepareBuffer(std::vector<char> filebuffer) {
union size {
uint64_t a;
char b[8];
};
union size t;
t.a = (uint64_t)filebuffer.size() * 8;
filebuffer.push_back((char)0x80); // Adding 0x80 byte
int padding = (int)((448 - (filebuffer.size() * 8 % 512)) / 8); //padding up to 448 bits
for (int i = 0; i < padding; ++i) {
filebuffer.push_back((char)0);
}
for (int i = 0; i < 4; i++) { //32 lower size bits
filebuffer.push_back(t.b[i]);
}
for (int i = 0; i < 4; ++i) { //32 higher bits
filebuffer.push_back(t.b[i+4]);
}
return filebuffer;
}
int main(int argc, char* argv[]) {
if (argc != 2) {
return 1;
}
std::vector<char> filebuffer = readFile(argv[1]);
filebuffer = prepareBuffer(filebuffer);
if((!filebuffer.size() % 16)) {
return 1;
}
std::vector<uint32_t> buffer;
for (int i = 0; i < filebuffer.size(); i+=4) { // 4 bytes to 32 bits
uint32_t a = (uint32_t)(filebuffer[i + 3] << 24) & 0xff000000;
uint32_t b = (uint32_t)(filebuffer[i + 2] << 16) & 0x00ff0000;
uint32_t c = (uint32_t)(filebuffer[i + 1] << 8) & 0x0000ff00;
uint32_t d = (uint32_t)(filebuffer[i + 0]) & 0x000000ff;
uint32_t temp = a | b | c | d;
buffer.push_back(temp);
}
std::string md5 = countMD5(buffer);
std::cout<<md5<<std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment