Main MRPT website > C++ reference for MRPT 1.5.7
md5.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 /* MD5
11  converted to C++ class by Frank Thilo (thilo@unix-ag.org)
12  for bzflag (http://www.bzflag.org)
13 
14  based on:
15 
16  md5.h and md5.c
17  reference implemantion of RFC 1321
18 
19  Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
20 rights reserved.
21 
22 License to copy and use this software is granted provided that it
23 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
24 Algorithm" in all material mentioning or referencing this software
25 or this function.
26 
27 License is also granted to make and use derivative works provided
28 that such works are identified as "derived from the RSA Data
29 Security, Inc. MD5 Message-Digest Algorithm" in all material
30 mentioning or referencing the derived work.
31 
32 RSA Data Security, Inc. makes no representations concerning either
33 the merchantability of this software or the suitability of this
34 software for any particular purpose. It is provided "as is"
35 without express or implied warranty of any kind.
36 
37 These notices must be retained in any copies of any part of this
38 documentation and/or software.
39 
40 */
41 
42 #include "base-precomp.h" // Precompiled headers
43 
44 
45 #include <mrpt/utils/md5.h>
46 
47 using namespace mrpt::utils;
48 using namespace std;
49 
50 #include <string>
51 #include <cstring>
52 #include <iostream>
53 #include <stdio.h>
54 
55 
56  // a small class for calculating MD5 hashes of strings or byte arrays
57  // it is not meant to be fast or secure
58  //
59  // usage: 1) feed it blocks of uchars with update()
60  // 2) finalize()
61  // 3) get hexdigest() string
62  // or
63  // MD5(std::string).hexdigest()
64  //
65  // assumes that char is 8 bit and int is 32 bit
66  class MD5
67  {
68  public:
69  typedef unsigned int size_type; // must be 32bit
70 
71  MD5();
72  MD5(const std::string& text);
73  void update(const unsigned char *buf, size_type length);
74  void update(const char *buf, size_type length);
75  MD5& finalize();
76  std::string hexdigest() const;
77  friend std::ostream& operator<<(std::ostream&, MD5 md5);
78 
79  private:
80  void init();
81  typedef unsigned char uint1; // 8bit
82  typedef unsigned int uint4; // 32bit
83  enum {blocksize = 64}; // VC6 won't eat a const static int here
84 
85  void transform(const uint1 block[blocksize]);
86  static void decode(uint4 output[], const uint1 input[], size_type len);
87  static void encode(uint1 output[], const uint4 input[], size_type len);
88 
89  bool finalized;
90  uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
91  uint4 count[2]; // 64bit counter for number of bits (lo, hi)
92  uint4 state[4]; // digest so far
93  uint1 digest[16]; // the result
94 
95  // low level logic operations
96  static inline uint4 F(uint4 x, uint4 y, uint4 z);
97  static inline uint4 G(uint4 x, uint4 y, uint4 z);
98  static inline uint4 H(uint4 x, uint4 y, uint4 z);
99  static inline uint4 I(uint4 x, uint4 y, uint4 z);
100  static inline uint4 rotate_left(uint4 x, int n);
101  static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
102  static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
103  static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
104  static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
105  };
106 
107 
108 
109 // Constants for MD5Transform routine.
110 #define S11 7
111 #define S12 12
112 #define S13 17
113 #define S14 22
114 #define S21 5
115 #define S22 9
116 #define S23 14
117 #define S24 20
118 #define S31 4
119 #define S32 11
120 #define S33 16
121 #define S34 23
122 #define S41 6
123 #define S42 10
124 #define S43 15
125 #define S44 21
126 
127 ///////////////////////////////////////////////
128 
129 // F, G, H and I are basic MD5 functions.
131  return (x&y) | (~x&z);
132 }
133 
135  return (x&z) | (y&~z);
136 }
137 
139  return x^y^z;
140 }
141 
143  return y ^ (x | ~z);
144 }
145 
146 // rotate_left rotates x left n bits.
148  return (x << n) | (x >> (32-n));
149 }
150 
151 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
152 // Rotation is separate from addition to prevent recomputation.
153 inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
154  a = rotate_left(a+ F(b,c,d) + x + ac, s) + b;
155 }
156 
157 inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
158  a = rotate_left(a + G(b,c,d) + x + ac, s) + b;
159 }
160 
161 inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
162  a = rotate_left(a + H(b,c,d) + x + ac, s) + b;
163 }
164 
165 inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
166  a = rotate_left(a + I(b,c,d) + x + ac, s) + b;
167 }
168 
169 //////////////////////////////////////////////
170 
171 // default ctor, just initailize
173 {
174  init();
175 }
176 
177 //////////////////////////////////////////////
178 
179 // nifty shortcut ctor, compute MD5 for string and finalize it right away
180 MD5::MD5(const std::string &text)
181 {
182  init();
183  update(text.c_str(), text.length());
184  finalize();
185 }
186 
187 //////////////////////////////
188 
189 void MD5::init()
190 {
191  finalized=false;
192 
193  count[0] = 0;
194  count[1] = 0;
195 
196  // load magic initialization constants.
197  state[0] = 0x67452301;
198  state[1] = 0xefcdab89;
199  state[2] = 0x98badcfe;
200  state[3] = 0x10325476;
201 }
202 
203 //////////////////////////////
204 
205 // decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
206 void MD5::decode(uint4 output[], const uint1 input[], size_type len)
207 {
208  for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
209  output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
210  (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
211 }
212 
213 //////////////////////////////
214 
215 // encodes input (uint4) into output (unsigned char). Assumes len is
216 // a multiple of 4.
217 void MD5::encode(uint1 output[], const uint4 input[], size_type len)
218 {
219  for (size_type i = 0, j = 0; j < len; i++, j += 4) {
220  output[j] = input[i] & 0xff;
221  output[j+1] = (input[i] >> 8) & 0xff;
222  output[j+2] = (input[i] >> 16) & 0xff;
223  output[j+3] = (input[i] >> 24) & 0xff;
224  }
225 }
226 
227 //////////////////////////////
228 
229 // apply MD5 algo on a block
230 void MD5::transform(const uint1 block[blocksize])
231 {
232  uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
233  decode (x, block, blocksize);
234 
235  /* Round 1 */
236  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
237  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
238  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
239  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
240  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
241  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
242  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
243  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
244  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
245  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
246  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
247  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
248  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
249  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
250  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
251  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
252 
253  /* Round 2 */
254  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
255  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
256  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
257  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
258  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
259  GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
260  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
261  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
262  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
263  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
264  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
265  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
266  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
267  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
268  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
269  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
270 
271  /* Round 3 */
272  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
273  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
274  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
275  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
276  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
277  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
278  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
279  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
280  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
281  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
282  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
283  HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
284  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
285  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
286  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
287  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
288 
289  /* Round 4 */
290  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
291  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
292  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
293  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
294  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
295  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
296  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
297  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
298  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
299  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
300  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
301  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
302  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
303  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
304  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
305  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
306 
307  state[0] += a;
308  state[1] += b;
309  state[2] += c;
310  state[3] += d;
311 
312  // Zeroize sensitive information.
313  memset(x, 0, sizeof x);
314 }
315 
316 //////////////////////////////
317 
318 // MD5 block update operation. Continues an MD5 message-digest
319 // operation, processing another message block
320 void MD5::update(const unsigned char input[], size_type length)
321 {
322  // compute number of bytes mod 64
323  size_type index = count[0] / 8 % blocksize;
324 
325  // Update number of bits
326  if ((count[0] += (length << 3)) < (length << 3))
327  count[1]++;
328  count[1] += (length >> 29);
329 
330  // number of bytes we need to fill in buffer
331  size_type firstpart = 64 - index;
332 
333  size_type i;
334 
335  // transform as many times as possible.
336  if (length >= firstpart)
337  {
338  // fill buffer first, transform
339  memcpy(&buffer[index], input, firstpart);
340  transform(buffer);
341 
342  // transform chunks of blocksize (64 bytes)
343  for (i = firstpart; i + blocksize <= length; i += blocksize)
344  transform(&input[i]);
345 
346  index = 0;
347  }
348  else
349  i = 0;
350 
351  // buffer remaining input
352  memcpy(&buffer[index], &input[i], length-i);
353 }
354 
355 //////////////////////////////
356 
357 // for convenience provide a verson with signed char
358 void MD5::update(const char input[], size_type length)
359 {
360  update((const unsigned char*)input, length);
361 }
362 
363 //////////////////////////////
364 
365 // MD5 finalization. Ends an MD5 message-digest operation, writing the
366 // the message digest and zeroizing the context.
368 {
369  static unsigned char padding[64] = {
370  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
371  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
372  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
373  };
374 
375  if (!finalized) {
376  // Save number of bits
377  unsigned char bits[8];
378  encode(bits, count, 8);
379 
380  // pad out to 56 mod 64.
381  size_type index = count[0] / 8 % 64;
382  size_type padLen = (index < 56) ? (56 - index) : (120 - index);
383  update(padding, padLen);
384 
385  // Append length (before padding)
386  update(bits, 8);
387 
388  // Store state in digest
389  encode(digest, state, 16);
390 
391  // Zeroize sensitive information.
392  memset(buffer, 0, sizeof buffer);
393  memset(count, 0, sizeof count);
394 
395  finalized=true;
396  }
397 
398  return *this;
399 }
400 
401 //////////////////////////////
402 
403 // return hex representation of digest as string
405 {
406  if (!finalized)
407  return "";
408 
409  char buf[33];
410  for (int i=0; i<16; i++)
411  sprintf(buf+i*2, "%02x", digest[i]);
412  buf[32]=0;
413 
414  return std::string(buf);
415 }
416 
417 //////////////////////////////
418 
419 std::ostream& operator<<(std::ostream& out, MD5 md5)
420 {
421  return out << md5.hexdigest();
422 }
423 
424 //////////////////////////////
425 
427 {
428  MD5 md5 = MD5(str);
429  return md5.hexdigest();
430 }
431 
432 std::string mrpt::utils::md5(const unsigned char * data, const size_t len)
433 {
434  ASSERT_(data)
435  MD5 md5;
436  md5.update(data,len);
437  md5.finalize();
438 
439  return md5.hexdigest();
440 }
441 
443 {
444  return mrpt::utils::md5(&str[0],str.size());
445 }
void BASE_IMPEXP memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) MRPT_NO_THROWS
An OS and compiler independent version of "memcpy".
Definition: os.cpp:358
GLuint GLuint GLsizei count
Definition: glext.h:3512
#define S43
Definition: md5.cpp:124
#define S34
Definition: md5.cpp:121
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
GLdouble GLdouble z
Definition: glext.h:3734
std::string BASE_IMPEXP md5(const std::string &str)
Computes the md5 of a block of data.
Definition: md5.cpp:426
GLuint buffer
Definition: glext.h:3775
void update(const unsigned char *buf, size_type length)
#define S22
Definition: md5.cpp:115
#define S11
Definition: md5.cpp:110
GLenum GLsizei n
Definition: glext.h:4618
Definition: md5.cpp:66
static void encode(uint1 output[], const uint4 input[], size_type len)
Definition: md5.cpp:217
STL namespace.
GLdouble s
Definition: glext.h:3602
GLenum GLsizei len
Definition: glext.h:4349
#define S44
Definition: md5.cpp:125
void transform(const uint1 block[blocksize])
Definition: md5.cpp:230
#define S42
Definition: md5.cpp:123
void init()
Definition: md5.cpp:189
#define S14
Definition: md5.cpp:113
GLuint index
Definition: glext.h:3891
#define S31
Definition: md5.cpp:118
const GLubyte * c
Definition: glext.h:5590
unsigned int uint4
Definition: md5.cpp:82
static uint4 G(uint4 x, uint4 y, uint4 z)
Definition: md5.cpp:134
GLubyte GLubyte b
Definition: glext.h:5575
static void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: md5.cpp:153
#define S13
Definition: md5.cpp:112
CStream BASE_IMPEXP & operator<<(mrpt::utils::CStream &s, const char *a)
Definition: CStream.cpp:130
GLsizei const GLchar ** string
Definition: glext.h:3919
static void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: md5.cpp:165
#define S21
Definition: md5.cpp:114
static void decode(uint4 output[], const uint1 input[], size_type len)
Definition: md5.cpp:206
#define S23
Definition: md5.cpp:116
static uint4 H(uint4 x, uint4 y, uint4 z)
Definition: md5.cpp:138
std::string hexdigest() const
Definition: md5.cpp:404
#define S12
Definition: md5.cpp:111
static uint4 rotate_left(uint4 x, int n)
Definition: md5.cpp:147
MD5 & finalize()
Definition: md5.cpp:367
bool finalized
Definition: md5.cpp:89
MD5()
Definition: md5.cpp:172
GLuint GLsizei GLsizei * length
Definition: glext.h:3900
GLenum GLenum GLenum input
Definition: glext.h:5716
static uint4 I(uint4 x, uint4 y, uint4 z)
Definition: md5.cpp:142
#define ASSERT_(f)
static void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: md5.cpp:161
GLenum GLint GLint y
Definition: glext.h:3516
int BASE_IMPEXP sprintf(char *buf, size_t bufSize, const char *format,...) MRPT_NO_THROWS MRPT_printf_format_check(3
An OS-independent version of sprintf (Notice the bufSize param, which may be ignored in some compiler...
Definition: os.cpp:191
#define S32
Definition: md5.cpp:119
#define S41
Definition: md5.cpp:122
GLenum GLint x
Definition: glext.h:3516
std::vector< uint8_t > vector_byte
GLuint GLenum GLenum transform
Definition: glext.h:6092
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:3520
GLubyte GLubyte GLubyte a
Definition: glext.h:5575
#define S24
Definition: md5.cpp:117
unsigned int size_type
Definition: md5.cpp:69
unsigned char uint1
Definition: md5.cpp:81
static uint4 F(uint4 x, uint4 y, uint4 z)
Definition: md5.cpp:130
static void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)
Definition: md5.cpp:157
#define S33
Definition: md5.cpp:120



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019