md5.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 
38 #ifndef __INCLUDE_MD5__
39 #define __INCLUDE_MD5__
40 
41 #include <cstring>
42 
43 #ifndef __INCLUDE_MIST_CONF_H__
44 #include "config/mist_conf.h"
45 #endif
46 
47 #ifndef __INCLUDE_MIST_ENDIAN__
48 #include "config/endian.h"
49 #endif
50 
51 #ifndef __INCLUDE_HASH_ALGORITHM__
52 #include "hash_algorithm.h"
53 #endif
54 
55 
56 // mist名前空間の始まり
58 
59 
62 
63 
65 class md2 : public hash_algorithm
66 {
67 private:
68  typedef hash_algorithm base;
69 
70 public:
73  typedef base::uint8 uint8;
74  typedef base::uint32 uint32;
75  typedef base::uint64 uint64;
76 
77 
78 public:
80  virtual void compute_hash( const void *bytes, uint64 length )
81  {
82  size_type len = static_cast< size_type >( length );
83  length *= 8;
84 
85  const uint8 *data = reinterpret_cast< const uint8 * >( bytes );
86  size_type R = len % 16;
87  size_type i, j, N16 = len / 16;
88  uint8 pad = static_cast< uint8 >( 16 - R );
89  uint8 P[ 32 ], *C = P + 16;
90  uint8 S[ 256 ] = { 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
91  19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76,
92  130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138,
93  23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142,
94  187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16,
95  137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, 39, 53, 62,
96  204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, 181, 209, 215,
97  94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, 150, 164, 125, 182,
98  118, 252, 107, 226, 156, 116, 4, 241, 69, 157, 112, 89, 100, 113, 135,
99  32, 134, 91, 207, 101, 230, 45, 168, 2, 27, 96, 37, 173, 174, 176,
100  185, 246, 28, 70, 97, 105, 52, 64, 126, 15, 85, 71, 163, 35, 221,
101  81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38, 44, 83, 13, 110,
102  133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82, 106, 220, 55,
103  200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74, 120, 136,
104  149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57, 242,
105  239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235, 117, 75, 10,
106  49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
107  };
108 
109  // 末尾のパディング用データを作成する
110  memset( P, 0, sizeof( uint8 ) * 32 );
111  for( i = 0 ; i < R ; i++ )
112  {
113  P[ i ] = data[ len - R + i ];
114  }
115  for( ; i < 16 ; i++ )
116  {
117  P[ i ] = pad;
118  }
119 
120  uint8 L = 0;
121 
122 
123  for( i = 0 ; i < N16 ; i++ )
124  {
125  for( j = 0 ; j < 16 ; j++ )
126  {
127  uint8 c = data[ i * 16 + j ];
128  // RFCのアルゴリズムが間違っている模様
129  // 付属のサンプルコードのほうに合わせた
130  L = C[ j ] ^= S[ c ^ L ];
131  }
132  }
133  for( j = 0 ; j < 16 ; j++ )
134  {
135  uint8 c = P[ j ];
136  // RFCのアルゴリズムが間違っている模様
137  // 付属のサンプルコードのほうに合わせた
138  L = C[ j ] ^= S[ c ^ L ];
139  }
140 
141 
142  uint8 X[ 48 ];
143  memset( X, 0, sizeof( uint8 ) * 48 );
144 
145  for( i = 0 ; i < N16 ; i++ )
146  {
147  for( j = 0 ; j < 16 ; j++ )
148  {
149  X[ 16 + j ] = data[ i * 16 + j ];
150  X[ 32 + j ] = X[ 16 + j ] ^ X[ j ];
151  }
152 
153  size_type t = 0;
154 
155  for( j = 0 ; j < 18 ; j++ )
156  {
157  for( size_type k = 0 ; k < 48 ; k++ )
158  {
159  t = X[ k ] ^= S[ t ];
160  }
161 
162  t = ( t + j ) & 0xff;
163  }
164  }
165 
166  for( i = 0 ; i < 2 ; i++ )
167  {
168  for( j = 0 ; j < 16 ; j++ )
169  {
170  X[ 16 + j ] = P[ i * 16 + j ];
171  X[ 32 + j ] = X[ 16 + j ] ^ X[ j ];
172  }
173 
174  size_type t = 0;
175 
176  for( j = 0 ; j < 18 ; j++ )
177  {
178  for( size_type k = 0 ; k < 48 ; k++ )
179  {
180  t = X[ k ] ^= S[ t ];
181  }
182 
183  t = ( t + j ) & 0xff;
184  }
185  }
186 
187  memcpy( digest, X, sizeof( uint8 ) * 16 );
188  }
189 
190 
192  virtual const std::string name( ) const{ return( "MD2" ); }
193 
194 
196  md2( ) : base( "8350e5a3e24c153df2275c9f80692773" ){ }
197 
199  md2( const std::string &str ) : base( 16 ) { base::compute_hash( str ); }
200 
202  md2( const void *data, uint64 len ) : base( 16 ){ compute_hash( data, len ); }
203 };
204 
205 
206 
208 class md4 : public hash_algorithm
209 {
210 private:
211  typedef hash_algorithm base;
212 
213 public:
216  typedef base::uint8 uint8;
219 
220 
221 protected:
222  uint32 R( uint32 a, uint32 s ){ return( ( a << s ) | ( a >> ( 32 - s ) ) ); }
223 
224  void FF( uint32 &a, uint32 b, uint32 c, uint32 d, uint32 xk, uint32 s )
225  {
226  a = R( a + ( ( b & c ) | ( ~b & d ) ) + xk, s );
227  }
228 
229  void GG( uint32 &a, uint32 b, uint32 c, uint32 d, uint32 xk, uint32 s )
230  {
231  a = R( a + ( ( b & c ) | ( b & d ) | ( d & c ) ) + xk + 0x5a827999, s );
232  }
233 
234  void HH( uint32 &a, uint32 b, uint32 c, uint32 d, uint32 xk, uint32 s )
235  {
236  a = R( a + ( b ^ c ^ d ) + xk + 0x6ed9eba1, s );
237  }
238 
239  void ToCurrentEndian( uint32 *x, size_type len )
240  {
241  for( size_type i = 0 ; i < len ; i++ )
242  {
243  x[ i ] = to_current_endian( byte_array< uint32 >( x[ i ] ), true ).get_value( );
244  }
245  }
246 
247  void FromCurrentEndian( uint32 *x, size_type len )
248  {
249  for( size_type i = 0 ; i < len ; i++ )
250  {
251  x[ i ] = from_current_endian( byte_array< uint32 >( x[ i ] ), true ).get_value( );
252  }
253  }
254 
255 
256  void Round( uint32 &a, uint32 &b, uint32 &c, uint32 &d, uint32 x[ 16 ] )
257  {
258  uint32 A = a;
259  uint32 B = b;
260  uint32 C = c;
261  uint32 D = d;
262 
263  // ワードブロックごとの処理を行う
264  FF( A, B, C, D, x[ 0 ], 3 ); FF( D, A, B, C, x[ 1 ], 7 ); FF( C, D, A, B, x[ 2 ], 11 ); FF( B, C, D, A, x[ 3 ], 19 );
265  FF( A, B, C, D, x[ 4 ], 3 ); FF( D, A, B, C, x[ 5 ], 7 ); FF( C, D, A, B, x[ 6 ], 11 ); FF( B, C, D, A, x[ 7 ], 19 );
266  FF( A, B, C, D, x[ 8 ], 3 ); FF( D, A, B, C, x[ 9 ], 7 ); FF( C, D, A, B, x[ 10 ], 11 ); FF( B, C, D, A, x[ 11 ], 19 );
267  FF( A, B, C, D, x[ 12 ], 3 ); FF( D, A, B, C, x[ 13 ], 7 ); FF( C, D, A, B, x[ 14 ], 11 ); FF( B, C, D, A, x[ 15 ], 19 );
268 
269  GG( A, B, C, D, x[ 0 ], 3 ); GG( D, A, B, C, x[ 4 ], 5 ); GG( C, D, A, B, x[ 8 ], 9 ); GG( B, C, D, A, x[ 12 ], 13 );
270  GG( A, B, C, D, x[ 1 ], 3 ); GG( D, A, B, C, x[ 5 ], 5 ); GG( C, D, A, B, x[ 9 ], 9 ); GG( B, C, D, A, x[ 13 ], 13 );
271  GG( A, B, C, D, x[ 2 ], 3 ); GG( D, A, B, C, x[ 6 ], 5 ); GG( C, D, A, B, x[ 10 ], 9 ); GG( B, C, D, A, x[ 14 ], 13 );
272  GG( A, B, C, D, x[ 3 ], 3 ); GG( D, A, B, C, x[ 7 ], 5 ); GG( C, D, A, B, x[ 11 ], 9 ); GG( B, C, D, A, x[ 15 ], 13 );
273 
274  HH( A, B, C, D, x[ 0 ], 3 ); HH( D, A, B, C, x[ 8 ], 9 ); HH( C, D, A, B, x[ 4 ], 11 ); HH( B, C, D, A, x[ 12 ], 15 );
275  HH( A, B, C, D, x[ 2 ], 3 ); HH( D, A, B, C, x[ 10 ], 9 ); HH( C, D, A, B, x[ 6 ], 11 ); HH( B, C, D, A, x[ 14 ], 15 );
276  HH( A, B, C, D, x[ 1 ], 3 ); HH( D, A, B, C, x[ 9 ], 9 ); HH( C, D, A, B, x[ 5 ], 11 ); HH( B, C, D, A, x[ 13 ], 15 );
277  HH( A, B, C, D, x[ 3 ], 3 ); HH( D, A, B, C, x[ 11 ], 9 ); HH( C, D, A, B, x[ 7 ], 11 ); HH( B, C, D, A, x[ 15 ], 15 );
278 
279  a += A;
280  b += B;
281  c += C;
282  d += D;
283  }
284 
285 public:
287  virtual void compute_hash( const void *bytes, uint64 length )
288  {
289  size_type len = static_cast< size_type >( length );
290  length *= 8;
291 
292  // 出力用のダイジェストバイト列を 32 ビット単位で処理できるようにする
293  uint32 &A = *reinterpret_cast< uint32 * >( digest );
294  uint32 &B = *reinterpret_cast< uint32 * >( digest + 4 );
295  uint32 &C = *reinterpret_cast< uint32 * >( digest + 8 );
296  uint32 &D = *reinterpret_cast< uint32 * >( digest + 12 );
297 
298  // ダイジェストバイト列の初期化
299  A = 0x67452301;
300  B = 0xefcdab89;
301  C = 0x98badcfe;
302  D = 0x10325476;
303 
304  size_type i;
305  uint32 x[ 16 ];
306  uint8 *xx = reinterpret_cast< uint8 * >( x );
307  const uint8 *data = reinterpret_cast< const uint8 * >( bytes );
308 
309  // 入力データに対してメッセージ処理を行う
310  for( i = 0 ; i + 64 < len ; i += 64 )
311  {
312  memcpy( xx, data + i, sizeof( uint8 ) * 64 );
313  ToCurrentEndian( x, 16 );
314  Round( A, B, C, D, x );
315  }
316 
317  size_type rest = len - i;
318 
319  // 最後にバイト長を足す分が存在しなければ,64バイトに拡張して処理する
320  if( rest >= 64 - 8 )
321  {
322  memcpy( xx, data + i, sizeof( uint8 ) * rest );
323  memset( xx + rest, 0, sizeof( uint8 ) * ( 64 - rest ) );
324  // 先頭のビットを 1 にする
325  xx[ rest ] = 0x80;
326 
327  // メッセージ処理を行う
328  ToCurrentEndian( x, 16 );
329  Round( A, B, C, D, x );
330 
331  // バイト長の分の処理を行う
332  memset( xx, 0, sizeof( uint8 ) * 64 );
333  x[ 14 ] = static_cast< uint32 >( length );
334  x[ 15 ] = static_cast< uint32 >( length >> 32 );
335 
336  // メッセージ処理を行う
337  Round( A, B, C, D, x );
338  }
339  else
340  {
341  memcpy( xx, data + i, sizeof( uint8 ) * rest );
342  memset( xx + rest, 0, sizeof( uint8 ) * ( 64 - rest ) );
343  // 先頭のビットを 1 にする
344  xx[ rest ] = 0x80;
345 
346  ToCurrentEndian( x, 16 );
347 
348  // バイト長の分の値を付加する
349  x[ 14 ] = static_cast< uint32 >( length );
350  x[ 15 ] = static_cast< uint32 >( length >> 32 );
351 
352  // メッセージ処理を行う
353  Round( A, B, C, D, x );
354  }
355 
356  FromCurrentEndian( reinterpret_cast< uint32 * >( digest ), 4 );
357  }
358 
359 
361  virtual const std::string name( ) const{ return( "MD4" ); }
362 
363 
365  md4( ) : base( "31d6cfe0d16ae931b73c59d7e0c089c0" ){ }
366 
368  md4( const std::string &str ) : base( 16 ) { base::compute_hash( str ); }
369 
371  md4( const void *data, uint64 len ) : base( 16 ){ compute_hash( data, len ); }
372 
373 };
374 
375 
376 
377 
378 
380 class md5 : public hash_algorithm
381 {
382 private:
383  typedef hash_algorithm base;
384 
385 public:
388  typedef base::uint8 uint8;
391 
392 
393 protected:
394  uint32 R( uint32 a, uint32 s ){ return( ( a << s ) | ( a >> ( 32 - s ) ) ); }
395 
396  void FF( uint32 &a, uint32 b, uint32 c, uint32 d, uint32 xk, uint32 s, uint32 ti )
397  {
398  a = b + R( a + ( ( b & c ) | ( ~b & d ) ) + xk + ti, s );
399  }
400 
401  void GG( uint32 &a, uint32 b, uint32 c, uint32 d, uint32 xk, uint32 s, uint32 ti )
402  {
403  a = b + R( a + ( ( b & d ) | ( ~d & c ) ) + xk + ti, s );
404  }
405 
406  void HH( uint32 &a, uint32 b, uint32 c, uint32 d, uint32 xk, uint32 s, uint32 ti )
407  {
408  a = b + R( a + ( b ^ c ^ d ) + xk + ti, s );
409  }
410 
411  void II( uint32 &a, uint32 b, uint32 c, uint32 d, uint32 xk, uint32 s, uint32 ti )
412  {
413  a = b + R( a + ( c ^ ( b | ~d ) ) + xk + ti, s );
414  }
415 
416  void ToCurrentEndian( uint32 *x, size_type len )
417  {
418  for( size_type i = 0 ; i < len ; i++ )
419  {
420  x[ i ] = to_current_endian( byte_array< uint32 >( x[ i ] ), true ).get_value( );
421  }
422  }
423 
424  void FromCurrentEndian( uint32 *x, size_type len )
425  {
426  for( size_type i = 0 ; i < len ; i++ )
427  {
428  x[ i ] = from_current_endian( byte_array< uint32 >( x[ i ] ), true ).get_value( );
429  }
430  }
431 
432 
433  void Round( uint32 &a, uint32 &b, uint32 &c, uint32 &d, uint32 x[ 16 ] )
434  {
435  uint32 A = a;
436  uint32 B = b;
437  uint32 C = c;
438  uint32 D = d;
439 
440  // ワードブロックごとの処理を行う
441  FF( A, B, C, D, x[ 0 ], 7, 0xd76aa478 );
442  FF( D, A, B, C, x[ 1 ], 12, 0xe8c7b756 );
443  FF( C, D, A, B, x[ 2 ], 17, 0x242070db );
444  FF( B, C, D, A, x[ 3 ], 22, 0xc1bdceee );
445  FF( A, B, C, D, x[ 4 ], 7, 0xf57c0faf );
446  FF( D, A, B, C, x[ 5 ], 12, 0x4787c62a );
447  FF( C, D, A, B, x[ 6 ], 17, 0xa8304613 );
448  FF( B, C, D, A, x[ 7 ], 22, 0xfd469501 );
449  FF( A, B, C, D, x[ 8 ], 7, 0x698098d8 );
450  FF( D, A, B, C, x[ 9 ], 12, 0x8b44f7af );
451  FF( C, D, A, B, x[ 10 ], 17, 0xffff5bb1 );
452  FF( B, C, D, A, x[ 11 ], 22, 0x895cd7be );
453  FF( A, B, C, D, x[ 12 ], 7, 0x6b901122 );
454  FF( D, A, B, C, x[ 13 ], 12, 0xfd987193 );
455  FF( C, D, A, B, x[ 14 ], 17, 0xa679438e );
456  FF( B, C, D, A, x[ 15 ], 22, 0x49b40821 );
457 
458  GG( A, B, C, D, x[ 1 ], 5, 0xf61e2562 );
459  GG( D, A, B, C, x[ 6 ], 9, 0xc040b340 );
460  GG( C, D, A, B, x[ 11 ], 14, 0x265e5a51 );
461  GG( B, C, D, A, x[ 0 ], 20, 0xe9b6c7aa );
462  GG( A, B, C, D, x[ 5 ], 5, 0xd62f105d );
463  GG( D, A, B, C, x[ 10 ], 9, 0x02441453 );
464  GG( C, D, A, B, x[ 15 ], 14, 0xd8a1e681 );
465  GG( B, C, D, A, x[ 4 ], 20, 0xe7d3fbc8 );
466  GG( A, B, C, D, x[ 9 ], 5, 0x21e1cde6 );
467  GG( D, A, B, C, x[ 14 ], 9, 0xc33707d6 );
468  GG( C, D, A, B, x[ 3 ], 14, 0xf4d50d87 );
469  GG( B, C, D, A, x[ 8 ], 20, 0x455a14ed );
470  GG( A, B, C, D, x[ 13 ], 5, 0xa9e3e905 );
471  GG( D, A, B, C, x[ 2 ], 9, 0xfcefa3f8 );
472  GG( C, D, A, B, x[ 7 ], 14, 0x676f02d9 );
473  GG( B, C, D, A, x[ 12 ], 20, 0x8d2a4c8a );
474 
475  HH( A, B, C, D, x[ 5 ], 4, 0xfffa3942 );
476  HH( D, A, B, C, x[ 8 ], 11, 0x8771f681 );
477  HH( C, D, A, B, x[ 11 ], 16, 0x6d9d6122 );
478  HH( B, C, D, A, x[ 14 ], 23, 0xfde5380c );
479  HH( A, B, C, D, x[ 1 ], 4, 0xa4beea44 );
480  HH( D, A, B, C, x[ 4 ], 11, 0x4bdecfa9 );
481  HH( C, D, A, B, x[ 7 ], 16, 0xf6bb4b60 );
482  HH( B, C, D, A, x[ 10 ], 23, 0xbebfbc70 );
483  HH( A, B, C, D, x[ 13 ], 4, 0x289b7ec6 );
484  HH( D, A, B, C, x[ 0 ], 11, 0xeaa127fa );
485  HH( C, D, A, B, x[ 3 ], 16, 0xd4ef3085 );
486  HH( B, C, D, A, x[ 6 ], 23, 0x04881d05 );
487  HH( A, B, C, D, x[ 9 ], 4, 0xd9d4d039 );
488  HH( D, A, B, C, x[ 12 ], 11, 0xe6db99e5 );
489  HH( C, D, A, B, x[ 15 ], 16, 0x1fa27cf8 );
490  HH( B, C, D, A, x[ 2 ], 23, 0xc4ac5665 );
491 
492  II( A, B, C, D, x[ 0 ], 6, 0xf4292244 );
493  II( D, A, B, C, x[ 7 ], 10, 0x432aff97 );
494  II( C, D, A, B, x[ 14 ], 15, 0xab9423a7 );
495  II( B, C, D, A, x[ 5 ], 21, 0xfc93a039 );
496  II( A, B, C, D, x[ 12 ], 6, 0x655b59c3 );
497  II( D, A, B, C, x[ 3 ], 10, 0x8f0ccc92 );
498  II( C, D, A, B, x[ 10 ], 15, 0xffeff47d );
499  II( B, C, D, A, x[ 1 ], 21, 0x85845dd1 );
500  II( A, B, C, D, x[ 8 ], 6, 0x6fa87e4f );
501  II( D, A, B, C, x[ 15 ], 10, 0xfe2ce6e0 );
502  II( C, D, A, B, x[ 6 ], 15, 0xa3014314 );
503  II( B, C, D, A, x[ 13 ], 21, 0x4e0811a1 );
504  II( A, B, C, D, x[ 4 ], 6, 0xf7537e82 );
505  II( D, A, B, C, x[ 11 ], 10, 0xbd3af235 );
506  II( C, D, A, B, x[ 2 ], 15, 0x2ad7d2bb );
507  II( B, C, D, A, x[ 9 ], 21, 0xeb86d391 );
508 
509  a += A;
510  b += B;
511  c += C;
512  d += D;
513  }
514 
515 public:
517  virtual void compute_hash( const void *bytes, uint64 length )
518  {
519  size_type len = static_cast< size_type >( length );
520  length *= 8;
521 
522  // 出力用のダイジェストバイト列を 32 ビット単位で処理できるようにする
523  uint32 &A = *reinterpret_cast< uint32 * >( digest );
524  uint32 &B = *reinterpret_cast< uint32 * >( digest + 4 );
525  uint32 &C = *reinterpret_cast< uint32 * >( digest + 8 );
526  uint32 &D = *reinterpret_cast< uint32 * >( digest + 12 );
527 
528  // ダイジェストバイト列の初期化
529  A = 0x67452301;
530  B = 0xefcdab89;
531  C = 0x98badcfe;
532  D = 0x10325476;
533 
534  size_type i;
535  uint32 x[ 16 ];
536  uint8 *xx = reinterpret_cast< uint8 * >( x );
537  const uint8 *data = reinterpret_cast< const uint8 * >( bytes );
538 
539  // 入力データに対してメッセージ処理を行う
540  for( i = 0 ; i + 64 < len ; i += 64 )
541  {
542  memcpy( xx, data + i, sizeof( uint8 ) * 64 );
543  ToCurrentEndian( x, 16 );
544  Round( A, B, C, D, x );
545  }
546 
547  size_type rest = len - i;
548 
549  // 最後にバイト長を足す分が存在しなければ,64バイトに拡張して処理する
550  if( rest >= 64 - 8 )
551  {
552  memcpy( xx, data + i, sizeof( uint8 ) * rest );
553  memset( xx + rest, 0, sizeof( uint8 ) * ( 64 - rest ) );
554  // 先頭のビットを 1 にする
555  xx[ rest ] = 0x80;
556 
557  // メッセージ処理を行う
558  ToCurrentEndian( x, 16 );
559  Round( A, B, C, D, x );
560 
561  // バイト長の分の処理を行う
562  memset( xx, 0, sizeof( uint8 ) * 64 );
563  x[ 14 ] = static_cast< uint32 >( length );
564  x[ 15 ] = static_cast< uint32 >( length >> 32 );
565 
566  // メッセージ処理を行う
567  Round( A, B, C, D, x );
568  }
569  else
570  {
571  memcpy( xx, data + i, sizeof( uint8 ) * rest );
572  memset( xx + rest, 0, sizeof( uint8 ) * ( 64 - rest ) );
573  // 先頭のビットを 1 にする
574  xx[ rest ] = 0x80;
575 
576  ToCurrentEndian( x, 16 );
577 
578  // バイト長の分の値を付加する
579  x[ 14 ] = static_cast< uint32 >( length );
580  x[ 15 ] = static_cast< uint32 >( length >> 32 );
581 
582  // メッセージ処理を行う
583  Round( A, B, C, D, x );
584  }
585 
586  FromCurrentEndian( reinterpret_cast< uint32 * >( digest ), 4 );
587  }
588 
589 
591  virtual const std::string name( ) const{ return( "MD5" ); }
592 
593 
595  md5( ) : base( "d41d8cd98f00b204e9800998ecf8427e" ){ }
596 
598  md5( const std::string &str ) : base( 16 ) { base::compute_hash( str ); }
599 
601  md5( const void *data, uint64 len ) : base( 16 ){ compute_hash( data, len ); }
602 
603 };
604 
605 
607 // ハッシュ関数グループの終わり
608 
609 
610 // mist名前空間の終わり
611 _MIST_END
612 
613 
614 #endif // __INCLUDE_MD5__
615 

Generated on Wed Nov 12 2014 19:44:18 for MIST by doxygen 1.8.1.2