52 small_t sizeof_thirty_two_bits = 4U ;
53 if(
sizeof(mask) > sizeof_thirty_two_bits )
58 state_type result = { a & ~mask , b & ~mask , c & ~mask , d & ~mask } ;
66 for(
small_t i = 0U ; i < n ; ++i )
83 void md5::digest::init()
99 void md5::digest::round1(
const block & m )
102 r(m,F,ABCD, 0, 7, 1); r(m,F,DABC, 1,12, 2); r(m,F,CDAB, 2,17, 3); r(m,F,BCDA, 3,22, 4);
103 r(m,F,ABCD, 4, 7, 5); r(m,F,DABC, 5,12, 6); r(m,F,CDAB, 6,17, 7); r(m,F,BCDA, 7,22, 8);
104 r(m,F,ABCD, 8, 7, 9); r(m,F,DABC, 9,12,10); r(m,F,CDAB,10,17,11); r(m,F,BCDA,11,22,12);
105 r(m,F,ABCD,12, 7,13); r(m,F,DABC,13,12,14); r(m,F,CDAB,14,17,15); r(m,F,BCDA,15,22,16);
108 void md5::digest::round2(
const block & m )
111 r(m,
G,ABCD, 1, 5,17); r(m,
G,DABC, 6, 9,18); r(m,
G,CDAB,11,14,19); r(m,
G,BCDA, 0,20,20);
112 r(m,
G,ABCD, 5, 5,21); r(m,
G,DABC,10, 9,22); r(m,
G,CDAB,15,14,23); r(m,
G,BCDA, 4,20,24);
113 r(m,
G,ABCD, 9, 5,25); r(m,
G,DABC,14, 9,26); r(m,
G,CDAB, 3,14,27); r(m,
G,BCDA, 8,20,28);
114 r(m,
G,ABCD,13, 5,29); r(m,
G,DABC, 2, 9,30); r(m,
G,CDAB, 7,14,31); r(m,
G,BCDA,12,20,32);
117 void md5::digest::round3(
const block & m )
120 r(m,H,ABCD, 5, 4,33); r(m,H,DABC, 8,11,34); r(m,H,CDAB,11,16,35); r(m,H,BCDA,14,23,36);
121 r(m,H,ABCD, 1, 4,37); r(m,H,DABC, 4,11,38); r(m,H,CDAB, 7,16,39); r(m,H,BCDA,10,23,40);
122 r(m,H,ABCD,13, 4,41); r(m,H,DABC, 0,11,42); r(m,H,CDAB, 3,16,43); r(m,H,BCDA, 6,23,44);
123 r(m,H,ABCD, 9, 4,45); r(m,H,DABC,12,11,46); r(m,H,CDAB,15,16,47); r(m,H,BCDA, 2,23,48);
126 void md5::digest::round4(
const block & m )
129 r(m,I,ABCD, 0, 6,49); r(m,I,DABC, 7,10,50); r(m,I,CDAB,14,15,51); r(m,I,BCDA, 5,21,52);
130 r(m,I,ABCD,12, 6,53); r(m,I,DABC, 3,10,54); r(m,I,CDAB,10,15,55); r(m,I,BCDA, 1,21,56);
131 r(m,I,ABCD, 8, 6,57); r(m,I,DABC,15,10,58); r(m,I,CDAB, 6,15,59); r(m,I,BCDA,13,21,60);
132 r(m,I,ABCD, 4, 6,61); r(m,I,DABC,11,10,62); r(m,I,CDAB, 2,15,63); r(m,I,BCDA, 9,21,64);
135 void md5::digest::operator()(
const block & m , aux_fn_t aux , Permutation p ,
small_t k ,
small_t s ,
small_t i )
137 if( p == ABCD ) a = op( m , aux , a , b , c , d , k , s , i ) ;
138 if( p == DABC ) d = op( m , aux , d , a , b , c , k , s , i ) ;
139 if( p == CDAB ) c = op( m , aux , c , d , a , b , k , s , i ) ;
140 if( p == BCDA ) b = op( m , aux , b , c , d , a , k , s , i ) ;
146 return b + rot32( s , ( a + (*aux)( b , c , d ) + m.X(k) + T(i) ) ) ;
152 big_t overflow_mask = ( 1UL << places ) - 1UL ;
153 big_t overflow = ( n >> ( 32U - places ) ) ;
154 return ( n << places ) | ( overflow & overflow_mask ) ;
159 return ( x & y ) | ( ~x & z ) ;
164 return ( x & z ) | ( y & ~z ) ;
174 return y ^ ( x | ~z ) ;
181 static big_t t_map[] =
247 return t_map[i-1UL] ;
255 result.reserve( 16U ) ;
256 result.append( raw(d.
a) ) ;
257 result.append( raw(d.
b) ) ;
258 result.append( raw(d.
c) ) ;
259 result.append( raw(d.
d) ) ;
266 result.reserve( 4U ) ;
267 result.append( 1U , static_cast<char>(n&0xffUL) ) ; n >>= 8U ;
268 result.append( 1U , static_cast<char>(n&0xffUL) ) ; n >>= 8U ;
269 result.append( 1U , static_cast<char>(n&0xffUL) ) ; n >>= 8U ;
270 result.append( 1U , static_cast<char>(n&0xffUL) ) ;
276 return rfc( d.
state() ) ;
282 result.reserve( 32U ) ;
283 result.append( str(d.
a) ) ;
284 result.append( str(d.
b) ) ;
285 result.append( str(d.
c) ) ;
286 result.append( str(d.
d) ) ;
293 result.reserve( 8U ) ;
294 result.append( str2(n&0xffUL) ) ; n >>= 8U ;
295 result.append( str2(n&0xffUL) ) ; n >>= 8U ;
296 result.append( str2(n&0xffUL) ) ; n >>= 8U ;
297 result.append( str2(n&0xffUL) ) ;
303 return str1((n>>4U)&0xfU) + str1(n&0xfU) ;
308 n = n <= 15U ? n : 0U ;
309 const char * map =
"0123456789abcdef" ;
318 m_end_value(end_value)
324 big_t result = length ;
331 small_t n = raw_byte_count + 64U ;
332 return n - ( ( raw_byte_count + 8U ) % 64U ) ;
337 small_t byte_count = rounded(raw_byte_count) + 8U ;
338 return byte_count / 64UL ;
343 small_t byte_index = ( m_block * 64U ) + ( dword_index * 4U ) ;
344 big_t result = x( byte_index + 3U ) ;
345 result <<= 8U ; result += x( byte_index + 2U ) ;
346 result <<= 8U ; result += x( byte_index + 1U ) ;
347 result <<= 8U ; result += x( byte_index + 0U ) ;
353 small_t length = m_s.length() ;
356 return static_cast<unsigned char>(m_s[i]) ;
358 else if( i < rounded(length) )
360 return i == length ? 128U : 0U ;
364 small_t byte_shift = i - rounded(length) ;
365 if( byte_shift >=
sizeof(
big_t) )
371 small_t bit_shift = byte_shift * 8U ;
373 big_t end_value = m_end_value >> bit_shift ;
374 return static_cast<small_t>( end_value & 0xffUL ) ;
394 m_buffer.append( s ) ;
395 m_length += s.length() ;
397 while( m_buffer.length() >= 64U )
399 block m( m_buffer , 0U , 0UL ) ;
401 m_buffer.erase( 0U , 64U ) ;
415 result.
d = m_digest.state() ;
416 result.
n = m_length ;
417 result.
s = m_buffer ;
void add(const string_type &)
Adds more message data.
size_type big_t
To hold at least 32 bits, maybe more. Try unsigned long on small systems.
void close()
Called after the last add().
size_type small_t
To hold at least a size_t. Must fit in a big_t.
big_t X(small_t) const
Returns a value from within the block. See RFC 1321.
block(const string_type &s, small_t block_offset, big_t end_value)
Constructor.
digest()
Default constructor.
Holds the md5 algorithm state. Used by md5::digest.
A helper class used by the md5::digest implementation to represent a 64-character data block...
std::string string_type
A string type.
static small_t blocks(small_t data_length)
Takes the total number of bytes in the input message and returns the number of 64-byte blocks...
A class that calculates an md5 digest from one or more 64-byte blocks of data using the algorithm des...
small_t size() const
Returns how many data bytes have been accumulated so far.
state_type state() const
Returns the internal state.
state_type state() const
Returns the current state.
static big_t end(small_t data_length)
Takes the total number of bytes in the input message and returns a value which can be passed to the c...
digest_stream()
Default constructor.
void add(const block &)
Adds a 64-byte block of the message.
< Holds the state of an md5 digest stream. Used by md5::digest_stream.