MD5Sum.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (C) 2014 by Ralf Kaestner *
3  * ralf.kaestner@gmail.com *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the Lesser GNU General Public License as published by*
7  * the Free Software Foundation; either version 3 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * Lesser GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the Lesser GNU General Public License *
16  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17  ******************************************************************************/
18 
20 
21 namespace variant_topic_tools {
22 
23 /*****************************************************************************/
24 /* Static initializations */
25 /*****************************************************************************/
26 
28  0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
29 };
30 
31 const boost::array<uint32_t, 64> MD5Sum::numBitRotations = {
32  7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
33  5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
34  4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
35  6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
36 };
37 
38 const boost::array<uint32_t, 64> MD5Sum::constants = {
39  0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
40  0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
41  0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
42  0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
43  0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
44  0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
45  0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
46  0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
47  0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
48  0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
49  0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
50  0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
51  0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
52  0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
53  0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
54  0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
55 };
56 
58  0x00000080, 0x00000000, 0x00000000, 0x00000000,
59  0x00000000, 0x00000000, 0x00000000, 0x00000000,
60  0x00000000, 0x00000000, 0x00000000, 0x00000000,
61  0x00000000, 0x00000000, 0x00000000, 0x00000000
62 };
63 
64 /*****************************************************************************/
65 /* Constructors and Destructor */
66 /*****************************************************************************/
67 
68 MD5Sum::MD5Sum(const std::string& text) {
69  clear();
70  update(text);
71 }
72 
73 MD5Sum::MD5Sum(const MD5Sum& src) :
74  digest(src.digest),
76  buffer(src.buffer) {
77 }
78 
80 }
81 
82 /*****************************************************************************/
83 /* Accessors */
84 /*****************************************************************************/
85 
87  const uint8_t* numDigestedBits = reinterpret_cast<const uint8_t*>(
88  this->numDigestedBits.data());
89  size_t i = this->numDigestedBits.size()*sizeof(uint32_t)-sizeof(size_t);
90 
91  return *reinterpret_cast<const size_t*>(&numDigestedBits[i]);
92 }
93 
95  Digest digest(this->digest);
97  Block buffer(this->buffer);
98 
99  finalize(digest, numDigestedBits, buffer);
100 
101  return digest;
102 }
103 
104 /*****************************************************************************/
105 /* Methods */
106 /*****************************************************************************/
107 
108 void MD5Sum::update(const std::string& text) {
109  if (!text.empty())
110  update(reinterpret_cast<const uint8_t*>(text.data()), text.length());
111 }
112 
113 void MD5Sum::update(const uint8_t* bytes, size_t numBytes) {
114  update(digest, numDigestedBits, buffer, bytes, numBytes);
115 }
116 
119 
120  numDigestedBits.fill(0);
121  buffer.fill(0);
122 }
123 
124 void MD5Sum::write(std::ostream& stream) const {
125  stream << toString();
126 }
127 
128 std::string MD5Sum::toString() const {
129  Digest digest = getDigest();
130 
131  char stringData[2*digest.size()*sizeof(uint32_t)+1];
132  const uint8_t* digestData = reinterpret_cast<const uint8_t*>(
133  digest.data());
134 
135  for (size_t i = 0; i < digest.size()*sizeof(uint32_t); ++i)
136  sprintf(&stringData[2*i], "%02x", digestData[i]);
137  stringData[2*digest.size()*sizeof(uint32_t)] = 0;
138 
139  return std::string(stringData);
140 }
141 
142 void MD5Sum::transform(const Block& block, Digest& digest) {
143  uint32_t a = digest[0];
144  uint32_t b = digest[1];
145  uint32_t c = digest[2];
146  uint32_t d = digest[3];
147 
148  for (size_t i = 0; i < 64; ++i) {
149  uint32_t f, g, h;
150 
151  if (i < 16) {
152  f = (b & c) | (~b & d);
153  g = i;
154  }
155  else if (i < 32) {
156  f = (b & d) | (c & ~d);
157  g = (5*i+1) % 16;
158  }
159  else if (i < 48) {
160  f = b ^ c ^ d;
161  g = (3*i+5) % 16;
162  }
163  else if (i < 64) {
164  f = c ^ (b | ~d);
165  g = (7*i) % 16;
166  }
167 
168  h = d;
169  d = c;
170  c = b;
171  b += rotateLeft(a+f+constants[i]+block[g], numBitRotations[i]);
172  a = h;
173  }
174 
175  digest[0] += a;
176  digest[1] += b;
177  digest[2] += c;
178  digest[3] += d;
179 }
180 
181 uint32_t MD5Sum::rotateLeft(uint32_t value, size_t numBits) {
182  return (value << numBits)|(value >> (sizeof(uint32_t)*8-numBits));
183 }
184 
186  const uint8_t* bytes, size_t numBytes) {
187  size_t i = numDigestedBits[0]/8 % 64;
188  size_t lengthOfFirstPart = 64-i;
189  size_t j = 0;
190 
191  if ((numDigestedBits[0] += (numBytes << 3)) < (numBytes << 3))
192  ++numDigestedBits[1];
193  numDigestedBits[1] += (numBytes >> 29);
194 
195  if (numBytes >= lengthOfFirstPart) {
196  std::copy(&bytes[0], &bytes[lengthOfFirstPart],
197  &reinterpret_cast<uint8_t*>(buffer.data())[i]);
198  transform(buffer, digest);
199 
200  for (j = lengthOfFirstPart; j+64 <= numBytes; j += 64) {
201  Block block;
202 
203  std::copy(&bytes[j], &bytes[j+64], reinterpret_cast<uint8_t*>(
204  block.data()));
205  transform(block, digest);
206  }
207 
208  i = 0;
209  }
210  else
211  j = 0;
212 
213  std::copy(&bytes[j], &bytes[numBytes],
214  &reinterpret_cast<uint8_t*>(buffer.data())[i]);
215 }
216 
218  Size finalNumDigestedBits(numDigestedBits);
219  size_t i = numDigestedBits[0]/8 % 64;
220  size_t paddedLength = (i < 56) ? 56-i : 120-i;
221 
222  update(digest, numDigestedBits, buffer, reinterpret_cast<const uint8_t*>(
223  padding.data()), paddedLength);
224  update(digest, numDigestedBits, buffer, reinterpret_cast<const uint8_t*>(
225  finalNumDigestedBits.data()), 8);
226 }
227 
228 /*****************************************************************************/
229 /* Operators */
230 /*****************************************************************************/
231 
232 MD5Sum& MD5Sum::operator<<(const std::string& text) {
233  update(text);
234  return *this;
235 }
236 
237 std::ostream& operator<<(std::ostream& stream, const MD5Sum& md5Sum) {
238  md5Sum.write(stream);
239  return stream;
240 }
241 
242 }
d
MD5Sum(const std::string &text=std::string())
Default constructor.
Definition: MD5Sum.cpp:68
f
boost::array< uint32_t, 4 > Digest
Definition of the MD5 sum digest type.
Definition: MD5Sum.h:40
MD5 sum computation algorithm.
Definition: MD5Sum.h:36
static const Block padding
Padding required to fill the last MD5 block for finalization.
Definition: MD5Sum.h:106
static uint32_t rotateLeft(uint32_t value, size_t numBits)
Perform bit rotation on a digest element.
Definition: MD5Sum.cpp:181
static void transform(const Block &block, Digest &digest)
Transform a block.
Definition: MD5Sum.cpp:142
void update(const std::string &text)
Update the MD5 sum using the given string.
Definition: MD5Sum.cpp:108
std::string toString() const
Convert the MD5 sum to a hexadecimal format string.
Definition: MD5Sum.cpp:128
boost::array< uint32_t, 16 > Block
Definition of the MD5 sum block type.
Definition: MD5Sum.h:89
void write(std::ostream &stream) const
Write the MD5 sum to a stream.
Definition: MD5Sum.cpp:124
Digest getDigest() const
Retrieve the MD5 sum&#39;s digest.
Definition: MD5Sum.cpp:94
Digest digest
The current digest.
Definition: MD5Sum.h:110
boost::array< uint32_t, 2 > Size
Definition of the MD5 sum size type.
Definition: MD5Sum.h:85
MD5Sum & operator<<(const std::string &text)
Stream operator for updating the MD5 sum.
Definition: MD5Sum.cpp:232
void clear()
Clear the MD5 sum.
Definition: MD5Sum.cpp:117
Header file providing the MD5Sum class interface.
static const boost::array< uint32_t, 64 > constants
Constants according to the MD5 algorithm.
Definition: MD5Sum.h:102
Block buffer
The buffered bytes which did not fit into the last block.
Definition: MD5Sum.h:118
static void finalize(Digest &digest, Size &numDigestedBits, Block &buffer)
Compute the finalized digest.
Definition: MD5Sum.cpp:217
size_t getNumDigestedBits() const
Retrieve the MD5 sum&#39;s number of digested bits.
Definition: MD5Sum.cpp:86
static const Digest initialDigest
Initial digest.
Definition: MD5Sum.h:93
Size numDigestedBits
The number of digested bits.
Definition: MD5Sum.h:114
~MD5Sum()
Destructor.
Definition: MD5Sum.cpp:79
static const boost::array< uint32_t, 64 > numBitRotations
Number of bit rotations per round according to the MD5 algorithm.
Definition: MD5Sum.h:98


variant_topic_tools
Author(s): Ralf Kaestner
autogenerated on Sat Jan 9 2021 03:56:49