31namespace digest_detail {
33static inline std::uint32_t
min(std::uint32_t x, std::uint32_t y) {
37static inline std::uint32_t
load32l(
const std::uint8_t* y) {
38 std::uint32_t res = 0;
39 for (
size_t i = 0; i != 4; ++i)
40 res |= std::uint32_t(y[i]) << (i * 8);
44static inline void store32l(std::uint32_t x, std::uint8_t* y) {
45 for (
size_t i = 0; i != 4; ++i)
46 y[i] = (x >> (i * 8)) & 255;
49static inline void store64l(std::uint64_t x, std::uint8_t* y) {
50 for (
size_t i = 0; i != 8; ++i)
51 y[i] = (x >> (i * 8)) & 255;
55std::uint32_t
F(
const std::uint32_t& x,
const std::uint32_t& y,
const std::uint32_t& z) {
56 return (z ^ (x & (y ^ z)));
59std::uint32_t
G(
const std::uint32_t& x,
const std::uint32_t& y,
const std::uint32_t& z) {
60 return (y ^ (z & (y ^ x)));
63std::uint32_t
H(
const std::uint32_t& x,
const std::uint32_t& y,
const std::uint32_t& z) {
67std::uint32_t
I(
const std::uint32_t& x,
const std::uint32_t& y,
const std::uint32_t& z) {
68 return (y ^ (x | (~z)));
71static inline void FF(std::uint32_t& a, std::uint32_t& b, std::uint32_t& c, std::uint32_t& d,
72 std::uint32_t M, std::uint32_t s, std::uint32_t t) {
73 a = (a +
F(b, c, d) + M + t);
77static inline void GG(std::uint32_t& a, std::uint32_t& b, std::uint32_t& c, std::uint32_t& d,
78 std::uint32_t M, std::uint32_t s, std::uint32_t t) {
79 a = (a +
G(b, c, d) + M + t);
83static inline void HH(std::uint32_t& a, std::uint32_t& b, std::uint32_t& c, std::uint32_t& d,
84 std::uint32_t M, std::uint32_t s, std::uint32_t t) {
85 a = (a +
H(b, c, d) + M + t);
89static inline void II(std::uint32_t& a, std::uint32_t& b, std::uint32_t& c, std::uint32_t& d,
90 std::uint32_t M, std::uint32_t s, std::uint32_t t) {
91 a = (a +
I(b, c, d) + M + t);
95static const std::uint8_t
Worder[64] = {
96 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
97 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,
98 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,
99 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9
103 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
104 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
105 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
106 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
110 0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL,
111 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL, 0x698098d8UL, 0x8b44f7afUL,
112 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL,
113 0x49b40821UL, 0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL,
114 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL, 0x21e1cde6UL,
115 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL,
116 0x676f02d9UL, 0x8d2a4c8aUL, 0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL,
117 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
118 0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL,
119 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL, 0xf4292244UL, 0x432aff97UL,
120 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL,
121 0x85845dd1UL, 0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL,
122 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
125static void md5_compress(std::uint32_t state[4],
const std::uint8_t* buf) {
126 std::uint32_t i, W[16], a, b, c, d, t;
129 for (i = 0; i < 16; i++) {
139 for (i = 0; i < 16; ++i) {
141 t = d, d = c, c = b, b = a, a = t;
144 for ( ; i < 32; ++i) {
146 t = d, d = c, c = b, b = a, a = t;
149 for ( ; i < 48; ++i) {
151 t = d, d = c, c = b, b = a, a = t;
154 for ( ; i < 64; ++i) {
156 t = d, d = c, c = b, b = a, a = t;
159 state[0] = state[0] + a;
160 state[1] = state[1] + b;
161 state[2] = state[2] + c;
162 state[3] = state[3] + d;
185 const std::uint32_t block_size =
sizeof(
MD5::buf_);
186 auto in =
static_cast<const std::uint8_t*
>(data);
190 if (
curlen_ == 0 && size >= block_size)
201 for (
const std::uint8_t* a = in; a != in + n; ++a, ++b) {
219 return process(str.data(), str.size());
248 for (
size_t i = 0; i < 4; i++) {
250 state_[i],
static_cast<std::uint8_t*
>(
digest) + (4 * i));
256 finalize(
const_cast<char*
>(out.data()));
272std::string
md5_hex(
const void* data, std::uint32_t size) {
280std::string
md5_hex_uc(
const void* data, std::uint32_t size) {
MD-5 processor without external dependencies.
void finalize(void *digest)
finalize computation and output 16 byte (128 bit) digest
std::string digest_hex()
finalize computation and return 16 byte (128 bit) digest hex encoded
std::string digest()
finalize computation and return 16 byte (128 bit) digest
std::string digest_hex_uc()
finalize computation and return 16 byte (128 bit) digest upper-case hex
MD5()
construct empty object.
static constexpr size_t kDigestLength
digest length in bytes
void process(const void *data, std::uint32_t size)
process more data
std::string md5_hex_uc(const void *data, std::uint32_t size)
process data and return 16 byte (128 bit) digest upper-case hex encoded
std::string md5_hex(const void *data, std::uint32_t size)
process data and return 16 byte (128 bit) digest hex encoded
static std::uint32_t rol32(const std::uint32_t &x, int i)
rol32 - generic
std::string hexdump_lc(const void *const data, size_t size)
Dump a (binary) string as a sequence of lowercase hexadecimal pairs.
std::string hexdump(const void *const data, size_t size)
Dump a (binary) string as a sequence of uppercase hexadecimal pairs.
static const std::uint8_t Worder[64]
static void GG(std::uint32_t &a, std::uint32_t &b, std::uint32_t &c, std::uint32_t &d, std::uint32_t M, std::uint32_t s, std::uint32_t t)
static void FF(std::uint32_t &a, std::uint32_t &b, std::uint32_t &c, std::uint32_t &d, std::uint32_t M, std::uint32_t s, std::uint32_t t)
static std::uint32_t min(std::uint32_t x, std::uint32_t y)
static const std::uint32_t Korder[64]
static std::uint32_t G(const std::uint32_t &x, const std::uint32_t &y, const std::uint32_t &z)
static void store32l(std::uint32_t x, std::uint8_t *y)
static const std::uint8_t Rorder[64]
static std::uint32_t F(const std::uint32_t &x, const std::uint32_t &y, const std::uint32_t &z)
static std::uint32_t H(const std::uint32_t &x, const std::uint32_t &y, const std::uint32_t &z)
static void md5_compress(std::uint32_t state[4], const std::uint8_t *buf)
static std::uint32_t load32l(const std::uint8_t *y)
static void store64l(std::uint64_t x, std::uint8_t *y)
static void HH(std::uint32_t &a, std::uint32_t &b, std::uint32_t &c, std::uint32_t &d, std::uint32_t M, std::uint32_t s, std::uint32_t t)
static void II(std::uint32_t &a, std::uint32_t &b, std::uint32_t &c, std::uint32_t &d, std::uint32_t M, std::uint32_t s, std::uint32_t t)
static std::uint32_t I(const std::uint32_t &x, const std::uint32_t &y, const std::uint32_t &z)