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