File indexing completed on 2025-07-14 08:48:45
0001 #ifndef BOOST_UUID_DETAIL_MD5_HPP_INCLUDED
0002 #define BOOST_UUID_DETAIL_MD5_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include <boost/uuid/detail/numeric_cast.hpp>
0030 #include <boost/uuid/uuid.hpp> // for version
0031 #include <string.h>
0032
0033 namespace boost {
0034 namespace uuids {
0035 namespace detail {
0036
0037 class md5
0038 {
0039 public:
0040
0041 typedef unsigned char digest_type[ 16 ];
0042
0043 md5()
0044 {
0045 MD5_Init(&ctx_);
0046 }
0047
0048 void process_byte(unsigned char byte)
0049 {
0050 MD5_Update(&ctx_, &byte, 1);
0051 }
0052
0053 void process_bytes(void const* buffer, std::size_t byte_count)
0054 {
0055 MD5_Update(&ctx_, buffer, detail::numeric_cast<unsigned long>(byte_count));
0056 }
0057
0058 void get_digest(digest_type& digest)
0059 {
0060 MD5_Final(digest, &ctx_);
0061 }
0062
0063 unsigned char get_version() const
0064 {
0065
0066 return uuid::version_name_based_md5;
0067 }
0068
0069 private:
0070
0071
0072 typedef std::uint32_t MD5_u32plus;
0073
0074 typedef struct {
0075 MD5_u32plus lo, hi;
0076 MD5_u32plus a, b, c, d;
0077 unsigned char buffer[64];
0078 MD5_u32plus block[16];
0079 } MD5_CTX;
0080
0081
0082
0083
0084
0085
0086
0087
0088 BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_F(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return ((z) ^ ((x) & ((y) ^ (z)))); }
0089 BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_G(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return ((y) ^ ((z) & ((x) ^ (y)))); }
0090 BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_H(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return (((x) ^ (y)) ^ (z)); }
0091 BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_H2(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return ((x) ^ ((y) ^ (z))); }
0092 BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_I(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return ((y) ^ ((x) | ~(z))); }
0093
0094
0095
0096
0097 #define BOOST_UUID_DETAIL_MD5_STEP(f, a, b, c, d, x, t, s) \
0098 (a) += f((b), (c), (d)) + (x) + (t); \
0099 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
0100 (a) += (b);
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 #if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
0118 #define BOOST_UUID_DETAIL_MD5_SET(n) \
0119 (memcpy(&ctx->block[(n)], &ptr[(n) * 4], sizeof(MD5_u32plus)), (ctx->block[(n)]))
0120 #define BOOST_UUID_DETAIL_MD5_GET(n) \
0121 (ctx->block[(n)])
0122 #else
0123 #define BOOST_UUID_DETAIL_MD5_SET(n) \
0124 (ctx->block[(n)] = \
0125 (MD5_u32plus)ptr[(n) * 4] | \
0126 ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
0127 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
0128 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
0129 #define BOOST_UUID_DETAIL_MD5_GET(n) \
0130 (ctx->block[(n)])
0131 #endif
0132
0133
0134
0135
0136
0137 const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
0138 {
0139 const unsigned char *ptr;
0140 MD5_u32plus a, b, c, d;
0141 MD5_u32plus saved_a, saved_b, saved_c, saved_d;
0142
0143 ptr = (const unsigned char *)data;
0144
0145 a = ctx->a;
0146 b = ctx->b;
0147 c = ctx->c;
0148 d = ctx->d;
0149
0150 do {
0151 saved_a = a;
0152 saved_b = b;
0153 saved_c = c;
0154 saved_d = d;
0155
0156
0157 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, a, b, c, d, BOOST_UUID_DETAIL_MD5_SET(0), 0xd76aa478, 7)
0158 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, d, a, b, c, BOOST_UUID_DETAIL_MD5_SET(1), 0xe8c7b756, 12)
0159 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, c, d, a, b, BOOST_UUID_DETAIL_MD5_SET(2), 0x242070db, 17)
0160 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, b, c, d, a, BOOST_UUID_DETAIL_MD5_SET(3), 0xc1bdceee, 22)
0161 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, a, b, c, d, BOOST_UUID_DETAIL_MD5_SET(4), 0xf57c0faf, 7)
0162 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, d, a, b, c, BOOST_UUID_DETAIL_MD5_SET(5), 0x4787c62a, 12)
0163 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, c, d, a, b, BOOST_UUID_DETAIL_MD5_SET(6), 0xa8304613, 17)
0164 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, b, c, d, a, BOOST_UUID_DETAIL_MD5_SET(7), 0xfd469501, 22)
0165 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, a, b, c, d, BOOST_UUID_DETAIL_MD5_SET(8), 0x698098d8, 7)
0166 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, d, a, b, c, BOOST_UUID_DETAIL_MD5_SET(9), 0x8b44f7af, 12)
0167 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, c, d, a, b, BOOST_UUID_DETAIL_MD5_SET(10), 0xffff5bb1, 17)
0168 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, b, c, d, a, BOOST_UUID_DETAIL_MD5_SET(11), 0x895cd7be, 22)
0169 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, a, b, c, d, BOOST_UUID_DETAIL_MD5_SET(12), 0x6b901122, 7)
0170 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, d, a, b, c, BOOST_UUID_DETAIL_MD5_SET(13), 0xfd987193, 12)
0171 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, c, d, a, b, BOOST_UUID_DETAIL_MD5_SET(14), 0xa679438e, 17)
0172 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, b, c, d, a, BOOST_UUID_DETAIL_MD5_SET(15), 0x49b40821, 22)
0173
0174
0175 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(1), 0xf61e2562, 5)
0176 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(6), 0xc040b340, 9)
0177 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(11), 0x265e5a51, 14)
0178 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(0), 0xe9b6c7aa, 20)
0179 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(5), 0xd62f105d, 5)
0180 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(10), 0x02441453, 9)
0181 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(15), 0xd8a1e681, 14)
0182 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(4), 0xe7d3fbc8, 20)
0183 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(9), 0x21e1cde6, 5)
0184 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(14), 0xc33707d6, 9)
0185 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(3), 0xf4d50d87, 14)
0186 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(8), 0x455a14ed, 20)
0187 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(13), 0xa9e3e905, 5)
0188 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(2), 0xfcefa3f8, 9)
0189 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(7), 0x676f02d9, 14)
0190 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(12), 0x8d2a4c8a, 20)
0191
0192
0193 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(5), 0xfffa3942, 4)
0194 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(8), 0x8771f681, 11)
0195 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(11), 0x6d9d6122, 16)
0196 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(14), 0xfde5380c, 23)
0197 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(1), 0xa4beea44, 4)
0198 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(4), 0x4bdecfa9, 11)
0199 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(7), 0xf6bb4b60, 16)
0200 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(10), 0xbebfbc70, 23)
0201 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(13), 0x289b7ec6, 4)
0202 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(0), 0xeaa127fa, 11)
0203 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(3), 0xd4ef3085, 16)
0204 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(6), 0x04881d05, 23)
0205 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(9), 0xd9d4d039, 4)
0206 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(12), 0xe6db99e5, 11)
0207 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(15), 0x1fa27cf8, 16)
0208 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(2), 0xc4ac5665, 23)
0209
0210
0211 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(0), 0xf4292244, 6)
0212 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(7), 0x432aff97, 10)
0213 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(14), 0xab9423a7, 15)
0214 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(5), 0xfc93a039, 21)
0215 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(12), 0x655b59c3, 6)
0216 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(3), 0x8f0ccc92, 10)
0217 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(10), 0xffeff47d, 15)
0218 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(1), 0x85845dd1, 21)
0219 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(8), 0x6fa87e4f, 6)
0220 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(15), 0xfe2ce6e0, 10)
0221 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(6), 0xa3014314, 15)
0222 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(13), 0x4e0811a1, 21)
0223 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(4), 0xf7537e82, 6)
0224 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(11), 0xbd3af235, 10)
0225 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(2), 0x2ad7d2bb, 15)
0226 BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(9), 0xeb86d391, 21)
0227
0228 a += saved_a;
0229 b += saved_b;
0230 c += saved_c;
0231 d += saved_d;
0232
0233 ptr += 64;
0234 } while (size -= 64);
0235
0236 ctx->a = a;
0237 ctx->b = b;
0238 ctx->c = c;
0239 ctx->d = d;
0240
0241 return ptr;
0242 }
0243
0244 void MD5_Init(MD5_CTX *ctx)
0245 {
0246 ctx->a = 0x67452301;
0247 ctx->b = 0xefcdab89;
0248 ctx->c = 0x98badcfe;
0249 ctx->d = 0x10325476;
0250
0251 ctx->lo = 0;
0252 ctx->hi = 0;
0253 }
0254
0255 void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
0256 {
0257 MD5_u32plus saved_lo;
0258 unsigned long used, available;
0259
0260 saved_lo = ctx->lo;
0261 if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
0262 ctx->hi++;
0263 ctx->hi += size >> 29;
0264
0265 used = saved_lo & 0x3f;
0266
0267 if (used) {
0268 available = 64 - used;
0269
0270 if (size < available) {
0271 memcpy(&ctx->buffer[used], data, size);
0272 return;
0273 }
0274
0275 memcpy(&ctx->buffer[used], data, available);
0276 data = (const unsigned char *)data + available;
0277 size -= available;
0278 body(ctx, ctx->buffer, 64);
0279 }
0280
0281 if (size >= 64) {
0282 data = body(ctx, data, size & ~(unsigned long)0x3f);
0283 size &= 0x3f;
0284 }
0285
0286 memcpy(ctx->buffer, data, size);
0287 }
0288
0289 #define BOOST_UUID_DETAIL_MD5_OUT(dst, src) \
0290 (dst)[0] = (unsigned char)(src); \
0291 (dst)[1] = (unsigned char)((src) >> 8); \
0292 (dst)[2] = (unsigned char)((src) >> 16); \
0293 (dst)[3] = (unsigned char)((src) >> 24);
0294
0295 void MD5_Final(unsigned char *result, MD5_CTX *ctx)
0296 {
0297 unsigned long used, available;
0298
0299 used = ctx->lo & 0x3f;
0300
0301 ctx->buffer[used++] = 0x80;
0302
0303 available = 64 - used;
0304
0305 if (available < 8) {
0306 memset(&ctx->buffer[used], 0, available);
0307 body(ctx, ctx->buffer, 64);
0308 used = 0;
0309 available = 64;
0310 }
0311
0312 memset(&ctx->buffer[used], 0, available - 8);
0313
0314 ctx->lo <<= 3;
0315 BOOST_UUID_DETAIL_MD5_OUT(&ctx->buffer[56], ctx->lo)
0316 BOOST_UUID_DETAIL_MD5_OUT(&ctx->buffer[60], ctx->hi)
0317
0318 body(ctx, ctx->buffer, 64);
0319
0320 BOOST_UUID_DETAIL_MD5_OUT(&result[0], ctx->a)
0321 BOOST_UUID_DETAIL_MD5_OUT(&result[4], ctx->b)
0322 BOOST_UUID_DETAIL_MD5_OUT(&result[8], ctx->c)
0323 BOOST_UUID_DETAIL_MD5_OUT(&result[12], ctx->d)
0324
0325 memset(ctx, 0, sizeof(*ctx));
0326 }
0327
0328 #undef BOOST_UUID_DETAIL_MD5_OUT
0329 #undef BOOST_UUID_DETAIL_MD5_SET
0330 #undef BOOST_UUID_DETAIL_MD5_GET
0331 #undef BOOST_UUID_DETAIL_MD5_STEP
0332
0333 MD5_CTX ctx_;
0334 };
0335
0336
0337 }
0338 }
0339 }
0340
0341 #endif