105 checksum.
update( source );
112 std::ostringstream result;
113 for (
size_t i = 0; i < digest.size(); ++i) {
114 result << std::hex << std::setfill(
'0') << std::setw(2);
115 result << static_cast<int>( digest[i] );
124 bool const all_hex = std::all_of( hex.begin(), hex.end(), [](
char c ){
125 return std::isxdigit( c );
127 if( hex.size() != 32 || ! all_hex ) {
128 throw std::runtime_error(
"Invalid MD5 hex string." );
144 for (
size_t i = 0; i < result.size(); ++i) {
146 auto const n = sscanf( &hex[ 2 * i ],
"%2" SCNx8, &(result[i]) );
148 throw std::runtime_error(
"Invalid MD5 hex string." );
184 update( s.c_str(), s.size() );
194 size_t cnt = is.gcount();
207 auto const* in_uchar =
reinterpret_cast<unsigned char const*
>( input );
208 update_( in_uchar, length);
219 static unsigned char padding[64] = {
220 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
222 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
226 unsigned char bits[8];
227 encode_(bits, count_, 8);
231 size_type padLen = (index < 56) ? (56 - index) : (120 - index);
232 update_(padding, padLen);
238 encode_( digest_.data(), state_, 16 );
241 memset(buffer_, 0,
sizeof buffer_);
242 memset(count_, 0,
sizeof count_);
258 state_[0] = 0x67452301;
259 state_[1] = 0xefcdab89;
260 state_[2] = 0x98badcfe;
261 state_[3] = 0x10325476;
270 if ((count_[0] += (length << 3)) < (length << 3)) {
273 count_[1] += (length >> 29);
280 if (length >= firstpart) {
282 memcpy( &buffer_[index], input, firstpart );
287 transform_( &input[i] );
295 memcpy( &buffer_[index], &input[i], length-i );
298 inline uint32_t MD5::F_(uint32_t x, uint32_t y, uint32_t z)
300 return ( x & y ) | ( ~x & z );
303 inline uint32_t MD5::G_(uint32_t x, uint32_t y, uint32_t z)
305 return ( x & z ) | ( y & ~z );
308 inline uint32_t MD5::H_(uint32_t x, uint32_t y, uint32_t z)
313 inline uint32_t MD5::I_(uint32_t x, uint32_t y, uint32_t z)
315 return y ^ ( x | ~z );
318 inline uint32_t MD5::rotate_left_(uint32_t x,
int n)
320 return (x << n) | (x >> (32-n));
323 inline void MD5::FF_(
324 uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac
326 a = rotate_left_(a+ F_(b,c,d) + x + ac, s) + b;
329 inline void MD5::GG_(
330 uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac
332 a = rotate_left_(a + G_(b,c,d) + x + ac, s) + b;
335 inline void MD5::HH_(
336 uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac
338 a = rotate_left_(a + H_(b,c,d) + x + ac, s) + b;
341 inline void MD5::II_(
342 uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint32_t s, uint32_t ac
344 a = rotate_left_(a + I_(b,c,d) + x + ac, s) + b;
349 uint32_t a = state_[0], b = state_[1], c = state_[2], d = state_[3], x[16];
350 decode_( x, block, MD5::BlockSize );
353 static uint32_t S11 = 7;
354 static uint32_t S12 = 12;
355 static uint32_t S13 = 17;
356 static uint32_t S14 = 22;
357 static uint32_t S21 = 5;
358 static uint32_t S22 = 9;
359 static uint32_t S23 = 14;
360 static uint32_t S24 = 20;
361 static uint32_t S31 = 4;
362 static uint32_t S32 = 11;
363 static uint32_t S33 = 16;
364 static uint32_t S34 = 23;
365 static uint32_t S41 = 6;
366 static uint32_t S42 = 10;
367 static uint32_t S43 = 15;
368 static uint32_t S44 = 21;
371 FF_ (a, b, c, d, x[ 0], S11, 0xd76aa478);
372 FF_ (d, a, b, c, x[ 1], S12, 0xe8c7b756);
373 FF_ (c, d, a, b, x[ 2], S13, 0x242070db);
374 FF_ (b, c, d, a, x[ 3], S14, 0xc1bdceee);
375 FF_ (a, b, c, d, x[ 4], S11, 0xf57c0faf);
376 FF_ (d, a, b, c, x[ 5], S12, 0x4787c62a);
377 FF_ (c, d, a, b, x[ 6], S13, 0xa8304613);
378 FF_ (b, c, d, a, x[ 7], S14, 0xfd469501);
379 FF_ (a, b, c, d, x[ 8], S11, 0x698098d8);
380 FF_ (d, a, b, c, x[ 9], S12, 0x8b44f7af);
381 FF_ (c, d, a, b, x[10], S13, 0xffff5bb1);
382 FF_ (b, c, d, a, x[11], S14, 0x895cd7be);
383 FF_ (a, b, c, d, x[12], S11, 0x6b901122);
384 FF_ (d, a, b, c, x[13], S12, 0xfd987193);
385 FF_ (c, d, a, b, x[14], S13, 0xa679438e);
386 FF_ (b, c, d, a, x[15], S14, 0x49b40821);
389 GG_ (a, b, c, d, x[ 1], S21, 0xf61e2562);
390 GG_ (d, a, b, c, x[ 6], S22, 0xc040b340);
391 GG_ (c, d, a, b, x[11], S23, 0x265e5a51);
392 GG_ (b, c, d, a, x[ 0], S24, 0xe9b6c7aa);
393 GG_ (a, b, c, d, x[ 5], S21, 0xd62f105d);
394 GG_ (d, a, b, c, x[10], S22, 0x2441453);
395 GG_ (c, d, a, b, x[15], S23, 0xd8a1e681);
396 GG_ (b, c, d, a, x[ 4], S24, 0xe7d3fbc8);
397 GG_ (a, b, c, d, x[ 9], S21, 0x21e1cde6);
398 GG_ (d, a, b, c, x[14], S22, 0xc33707d6);
399 GG_ (c, d, a, b, x[ 3], S23, 0xf4d50d87);
400 GG_ (b, c, d, a, x[ 8], S24, 0x455a14ed);
401 GG_ (a, b, c, d, x[13], S21, 0xa9e3e905);
402 GG_ (d, a, b, c, x[ 2], S22, 0xfcefa3f8);
403 GG_ (c, d, a, b, x[ 7], S23, 0x676f02d9);
404 GG_ (b, c, d, a, x[12], S24, 0x8d2a4c8a);
407 HH_ (a, b, c, d, x[ 5], S31, 0xfffa3942);
408 HH_ (d, a, b, c, x[ 8], S32, 0x8771f681);
409 HH_ (c, d, a, b, x[11], S33, 0x6d9d6122);
410 HH_ (b, c, d, a, x[14], S34, 0xfde5380c);
411 HH_ (a, b, c, d, x[ 1], S31, 0xa4beea44);
412 HH_ (d, a, b, c, x[ 4], S32, 0x4bdecfa9);
413 HH_ (c, d, a, b, x[ 7], S33, 0xf6bb4b60);
414 HH_ (b, c, d, a, x[10], S34, 0xbebfbc70);
415 HH_ (a, b, c, d, x[13], S31, 0x289b7ec6);
416 HH_ (d, a, b, c, x[ 0], S32, 0xeaa127fa);
417 HH_ (c, d, a, b, x[ 3], S33, 0xd4ef3085);
418 HH_ (b, c, d, a, x[ 6], S34, 0x4881d05);
419 HH_ (a, b, c, d, x[ 9], S31, 0xd9d4d039);
420 HH_ (d, a, b, c, x[12], S32, 0xe6db99e5);
421 HH_ (c, d, a, b, x[15], S33, 0x1fa27cf8);
422 HH_ (b, c, d, a, x[ 2], S34, 0xc4ac5665);
425 II_ (a, b, c, d, x[ 0], S41, 0xf4292244);
426 II_ (d, a, b, c, x[ 7], S42, 0x432aff97);
427 II_ (c, d, a, b, x[14], S43, 0xab9423a7);
428 II_ (b, c, d, a, x[ 5], S44, 0xfc93a039);
429 II_ (a, b, c, d, x[12], S41, 0x655b59c3);
430 II_ (d, a, b, c, x[ 3], S42, 0x8f0ccc92);
431 II_ (c, d, a, b, x[10], S43, 0xffeff47d);
432 II_ (b, c, d, a, x[ 1], S44, 0x85845dd1);
433 II_ (a, b, c, d, x[ 8], S41, 0x6fa87e4f);
434 II_ (d, a, b, c, x[15], S42, 0xfe2ce6e0);
435 II_ (c, d, a, b, x[ 6], S43, 0xa3014314);
436 II_ (b, c, d, a, x[13], S44, 0x4e0811a1);
437 II_ (a, b, c, d, x[ 4], S41, 0xf7537e82);
438 II_ (d, a, b, c, x[11], S42, 0xbd3af235);
439 II_ (c, d, a, b, x[ 2], S43, 0x2ad7d2bb);
440 II_ (b, c, d, a, x[ 9], S44, 0xeb86d391);
448 memset(x, 0,
sizeof x);
451 void MD5::decode_( uint32_t output[],
const uint8_t input[],
size_type len )
453 for (
unsigned int i = 0, j = 0; j < len; i++, j += 4) {
455 = ((uint32_t)input[j])
456 | (((uint32_t)input[j+1]) << 8)
457 | (((uint32_t)input[j+2]) << 16)
458 | (((uint32_t)input[j+3]) << 24)
463 void MD5::encode_( uint8_t output[],
const uint32_t input[],
size_type len )
465 for (
size_type i = 0, j = 0; j < len; i++, j += 4) {
466 output[j] = input[i] & 0xff;
467 output[j+1] = (input[i] >> 8) & 0xff;
468 output[j+2] = (input[i] >> 16) & 0xff;
469 output[j+3] = (input[i] >> 24) & 0xff;
Calculate MD5 hashes for strings and files.
MD5()
Initialize the object for use.
std::string final_hex()
Finish the calculation, prepare the object for next use, and return the hash.
void update(std::shared_ptr< BaseInputSource > source)
static std::string read_hex(std::shared_ptr< BaseInputSource > source)
Calculate the checksum for the content of an input source.
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
std::array< uint8_t, 16 > DigestType
Store an MD5 digest.
static DigestType read_digest(std::shared_ptr< BaseInputSource > source)
Calculate the hash digest for the content of an input source.
static const size_t BlockSize
void clear()
Reset to initial state, that is, delete any intermediate input from update() calls.
DigestType final_digest()
Finish the calculation, prepare the object for next use, and return the digest.
static DigestType hex_to_digest(std::string const &hex)
double length(Tree const &tree)
Get the length of the tree, i.e., the sum of all branch lengths.
static std::string digest_to_hex(DigestType const &digest)