MD5.cpp
Go to the documentation of this file.
1 /* MD5
2 converted to C++ class by Frank Thilo (thilo@unix-ag.org)
3 for bzflag (http://www.bzflag.org)
4 
5 based on:
6 
7 md5.h and md5.c
8 reference implemantion of RFC 1321
9 
10 Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
11 rights reserved.
12 
13 License to copy and use this software is granted provided that it
14 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
15 Algorithm" in all material mentioning or referencing this software
16 or this function.
17 
18 License is also granted to make and use derivative works provided
19 that such works are identified as "derived from the RSA Data
20 Security, Inc. MD5 Message-Digest Algorithm" in all material
21 mentioning or referencing the derived work.
22 
23 RSA Data Security, Inc. makes no representations concerning either
24 the merchantability of this software or the suitability of this
25 software for any particular purpose. It is provided "as is"
26 without express or implied warranty of any kind.
27 
28 These notices must be retained in any copies of any part of this
29 documentation and/or software.
30 
31 */
32 
33 /* interface header */
34 #include "MD5.h"
35 
36 /* system implementation headers */
37 #include <cstdio>
38 #include <cstring> // memset/memcpy
39 #include <algorithm> // for min
40 #include <limits> // for int max
41 
42 // suppress snprintf warnings
43 
44 namespace visionary
45 {
46 
47 // Constants for MD5Transform routine.
48 #define S11 7
49 #define S12 12
50 #define S13 17
51 #define S14 22
52 #define S21 5
53 #define S22 9
54 #define S23 14
55 #define S24 20
56 #define S31 4
57 #define S32 11
58 #define S33 16
59 #define S34 23
60 #define S41 6
61 #define S42 10
62 #define S43 15
63 #define S44 21
64 
66 
67 // F, G, H and I are basic MD5 functions.
68 inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) {
69  return (x & y) | (~x & z);
70 }
71 
72 inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) {
73  return (x & z) | (y & ~z);
74 }
75 
76 inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) {
77  return x ^ y^z;
78 }
79 
80 inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) {
81  return y ^ (x | ~z);
82 }
83 
84 // rotate_left rotates x left n bits.
85 inline MD5::uint4 MD5::rotate_left(uint4 x, int n) {
86  return (x << n) | (x >> (32 - n));
87 }
88 
89 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
90 // Rotation is separate from addition to prevent recomputation.
91 inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
92  a = rotate_left(a + F(b, c, d) + x + ac, s) + b;
93 }
94 
95 inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
96  a = rotate_left(a + G(b, c, d) + x + ac, s) + b;
97 }
98 
99 inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
100  a = rotate_left(a + H(b, c, d) + x + ac, s) + b;
101 }
102 
103 inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
104  a = rotate_left(a + I(b, c, d) + x + ac, s) + b;
105 }
106 
108 
109 // default ctor, just initailize
111 {
112  init();
113 }
114 
116 
117 // nifty shortcut ctor, compute MD5 for string and finalize it right away
118 MD5::MD5(const std::string &text)
119 {
120  init();
121  const size_t txtlen = text.length();
122  const size_t max_txtlen = std::numeric_limits<size_type>::max();
123  update(text.c_str(), static_cast<size_type>(std::min(txtlen, max_txtlen)));
124  finalize();
125 }
126 
128 
129 void MD5::init()
130 {
131  finalized = false;
132 
133  count[0] = 0;
134  count[1] = 0;
135 
136  // load magic initialization constants.
137  state[0] = 0x67452301;
138  state[1] = 0xefcdab89;
139  state[2] = 0x98badcfe;
140  state[3] = 0x10325476;
141 }
142 
144 
145 // decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
146 void MD5::decode(uint4 output[], const uint1 input[], size_type len)
147 {
148  for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
149  output[i] = ((uint4)input[j]) | (((uint4)input[j + 1]) << 8) |
150  (((uint4)input[j + 2]) << 16) | (((uint4)input[j + 3]) << 24);
151 }
152 
154 
155 // encodes input (uint4) into output (unsigned char). Assumes len is
156 // a multiple of 4.
157 void MD5::encode(uint1 output[], const uint4 input[], size_type len)
158 {
159  for (size_type i = 0, j = 0; j < len; i++, j += 4) {
160  output[j] = input[i] & 0xff;
161  output[j + 1] = (input[i] >> 8) & 0xff;
162  output[j + 2] = (input[i] >> 16) & 0xff;
163  output[j + 3] = (input[i] >> 24) & 0xff;
164  }
165 }
166 
168 
169 // apply MD5 algo on a block
170 void MD5::transform(const uint1 block[blocksize])
171 {
172  uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
173  decode(x, block, blocksize);
174 
175  /* Round 1 */
176  FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
177  FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
178  FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
179  FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
180  FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
181  FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
182  FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
183  FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
184  FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
185  FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
186  FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
187  FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
188  FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
189  FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
190  FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
191  FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
192 
193  /* Round 2 */
194  GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
195  GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
196  GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
197  GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
198  GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
199  GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
200  GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
201  GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
202  GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
203  GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
204  GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
205  GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
206  GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
207  GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
208  GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
209  GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
210 
211  /* Round 3 */
212  HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
213  HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
214  HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
215  HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
216  HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
217  HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
218  HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
219  HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
220  HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
221  HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
222  HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
223  HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
224  HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
225  HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
226  HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
227  HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
228 
229  /* Round 4 */
230  II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
231  II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
232  II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
233  II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
234  II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
235  II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
236  II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
237  II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
238  II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
239  II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
240  II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
241  II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
242  II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
243  II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
244  II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
245  II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
246 
247  state[0] += a;
248  state[1] += b;
249  state[2] += c;
250  state[3] += d;
251 
252  // Zeroize sensitive information.
253  std::memset(x, 0, sizeof x);
254 }
255 
257 
258 // MD5 block update operation. Continues an MD5 message-digest
259 // operation, processing another message block
260 void MD5::update(const unsigned char input[], size_type length)
261 {
262  // compute number of bytes mod 64
263  size_type index = count[0] / 8 % blocksize;
264 
265  // Update number of bits
266  if ((count[0] += (length << 3)) < (length << 3))
267  count[1]++;
268  count[1] += (length >> 29);
269 
270  // number of bytes we need to fill in buffer
271  size_type firstpart = 64 - index;
272 
273  size_type i;
274 
275  // transform as many times as possible.
276  if (length >= firstpart)
277  {
278  // fill buffer first, transform
279  std::memcpy(&buffer[index], input, firstpart);
280  transform(buffer);
281 
282  // transform chunks of blocksize (64 bytes)
283  for (i = firstpart; i + blocksize <= length; i += blocksize)
284  transform(&input[i]);
285 
286  index = 0;
287  }
288  else
289  i = 0;
290 
291  // buffer remaining input
292  memcpy(&buffer[index], &input[i], length - i);
293 }
294 
296 
297 // for convenience provide a verson with signed char
298 void MD5::update(const char input[], size_type length)
299 {
300  update((const unsigned char*)input, length);
301 }
302 
304 
305 // MD5 finalization. Ends an MD5 message-digest operation, writing the
306 // the message digest and zeroizing the context.
308 {
309  static unsigned char padding[64] = {
310  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
311  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
312  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
313  };
314 
315  if (!finalized) {
316  // Save number of bits
317  unsigned char bits[8];
318  encode(bits, count, 8);
319 
320  // pad out to 56 mod 64.
321  size_type index = count[0] / 8 % 64;
322  size_type padLen = (index < 56) ? (56 - index) : (120 - index);
323  update(padding, padLen);
324 
325  // Append length (before padding)
326  update(bits, 8);
327 
328  // Store state in digest
329  encode(digest, state, 16);
330 
331  // Zeroize sensitive information.
332  std::memset(buffer, 0, sizeof buffer);
333  std::memset(count, 0, sizeof count);
334 
335  finalized = true;
336  }
337 
338  return *this;
339 }
340 
342 
343 // return hex representation of digest as string
344 std::string MD5::hexdigest() const
345 {
346  if (!finalized)
347  return "";
348 
349  char buf[33];
350  for (int i = 0; i<16; i++)
351  sprintf(buf + i * 2, "%02x", digest[i]);
352  buf[32] = 0;
353 
354  return {buf};
355 }
356 
357 const unsigned char* MD5::getDigest() const
358 {
359  return digest;
360 }
361 
362 std::ostream& operator<<(std::ostream& out, const MD5 &md5)
363 {
364  return out << md5.hexdigest();
365 }
366 
368 
369 std::string md5(const std::string& str)
370 {
371  MD5 md5 = MD5(str);
372 
373  return md5.hexdigest();
374 }
375 
376 }
S21
#define S21
Definition: MD5.cpp:52
visionary::MD5::init
void init()
Definition: MD5.cpp:129
visionary::MD5::G
static uint4 G(uint4 x, uint4 y, uint4 z)
Definition: MD5.cpp:72
visionary::MD5::size_type
unsigned int size_type
Definition: MD5.h:55
S22
#define S22
Definition: MD5.cpp:53
visionary::md5
std::string md5(const std::string &str)
Definition: MD5.cpp:369
visionary::MD5::count
uint4 count[2]
Definition: MD5.h:79
S13
#define S13
Definition: MD5.cpp:50
visionary
Definition: MD5.cpp:44
visionary::MD5::finalized
bool finalized
Definition: MD5.h:77
visionary::MD5::finalize
MD5 & finalize()
Definition: MD5.cpp:307
s
XmlRpcServer s
visionary::operator<<
std::ostream & operator<<(std::ostream &out, const MD5 &md5)
Definition: MD5.cpp:362
visionary::MD5::digest
uint1 digest[16]
Definition: MD5.h:81
visionary::MD5::decode
static void decode(uint4 output[], const uint1 input[], size_type len)
Definition: MD5.cpp:146
visionary::MD5::HH
static void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: MD5.cpp:99
visionary::MD5::encode
static void encode(uint1 output[], const uint4 input[], size_type len)
Definition: MD5.cpp:157
S32
signed int S32
S12
#define S12
Definition: MD5.cpp:49
MD5.h
S44
#define S44
Definition: MD5.cpp:63
visionary::MD5::update
void update(const unsigned char *buf, size_type length)
S42
#define S42
Definition: MD5.cpp:61
visionary::MD5::MD5
MD5()
Definition: MD5.cpp:110
visionary::MD5
Definition: MD5.h:52
visionary::MD5::II
static void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: MD5.cpp:103
visionary::MD5::getDigest
const unsigned char * getDigest() const
Definition: MD5.cpp:357
visionary::MD5::buffer
uint1 buffer[blocksize]
Definition: MD5.h:78
visionary::MD5::uint4
unsigned int uint4
Definition: MD5.h:70
visionary::MD5::transform
void transform(const uint1 block[blocksize])
Definition: MD5.cpp:170
visionary::MD5::I
static uint4 I(uint4 x, uint4 y, uint4 z)
Definition: MD5.cpp:80
d
d
visionary::MD5::FF
static void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: MD5.cpp:91
S11
#define S11
Definition: MD5.cpp:48
visionary::MD5::F
static uint4 F(uint4 x, uint4 y, uint4 z)
Definition: MD5.cpp:68
S43
#define S43
Definition: MD5.cpp:62
visionary::MD5::hexdigest
std::string hexdigest() const
Definition: MD5.cpp:344
visionary::MD5::GG
static void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: MD5.cpp:95
visionary::MD5::rotate_left
static uint4 rotate_left(uint4 x, int n)
Definition: MD5.cpp:85
boost::iterators::i
D const & i
Definition: iterator_facade.hpp:956
S34
#define S34
Definition: MD5.cpp:59
S14
#define S14
Definition: MD5.cpp:51
visionary::MD5::state
uint4 state[4]
Definition: MD5.h:80
length
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
visionary::MD5::uint1
unsigned char uint1
Definition: MD5.h:69
visionary::MD5::blocksize
@ blocksize
Definition: MD5.h:71
S24
#define S24
Definition: MD5.cpp:55
S31
#define S31
Definition: MD5.cpp:56
visionary::MD5::H
static uint4 H(uint4 x, uint4 y, uint4 z)
Definition: MD5.cpp:76
S23
#define S23
Definition: MD5.cpp:54
S41
#define S41
Definition: MD5.cpp:60
S33
#define S33
Definition: MD5.cpp:58


sick_visionary_ros
Author(s): SICK AG TechSupport 3D Snapshot
autogenerated on Thu Feb 8 2024 03:44:21