00001
00002 #ifndef CXXUTILS_MD5_H
00003 #define CXXUTILS_MD5_H 1
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include <string>
00047
00048
00049
00050
00051 #define S11 7
00052 #define S12 12
00053 #define S13 17
00054 #define S14 22
00055 #define S21 5
00056 #define S22 9
00057 #define S23 14
00058 #define S24 20
00059 #define S31 4
00060 #define S32 11
00061 #define S33 16
00062 #define S34 23
00063 #define S41 6
00064 #define S42 10
00065 #define S43 15
00066 #define S44 21
00067
00068 class MD5 {
00069 public:
00070 MD5 (unsigned char* buffer, unsigned long len);
00071 MD5 ();
00072 void update (unsigned char *input, unsigned int input_length);
00073
00074 void finalize ();
00075
00076
00077 void raw_digest (unsigned char *buff);
00078
00079 std::string hex_digest ();
00080
00081 private:
00082
00083 unsigned int m_state[4];
00084 unsigned int m_count[2];
00085 unsigned char m_buffer[64];
00086 unsigned char m_digest[16];
00087 unsigned char m_finalized;
00088
00089
00090 void init ();
00091 void transform (unsigned char *buffer);
00092
00093
00094 static void encode (unsigned char *dest, unsigned int *src, unsigned int length);
00095 static void decode (unsigned int *dest, unsigned char *src, unsigned int length);
00096
00097
00098 static inline unsigned int rotate_left (unsigned int x, unsigned int n)
00099 { return (x << n) | (x >> (32-n)); }
00100
00101 static inline unsigned int F(unsigned int x, unsigned int y, unsigned int z)
00102 { return (x & y) | (~x & z); }
00103 static inline unsigned int G(unsigned int x, unsigned int y, unsigned int z)
00104 { return (x & z) | (y & ~z); }
00105 static inline unsigned int H(unsigned int x, unsigned int y, unsigned int z)
00106 { return x ^ y ^ z; }
00107 static inline unsigned int I(unsigned int x, unsigned int y, unsigned int z)
00108 { return y ^ (x | ~z); }
00109
00110
00111
00112 static inline void FF (unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac)
00113 {
00114 a += F(b, c, d) + x + ac;
00115 a = rotate_left(a, s) + b;
00116 }
00117 static inline void GG (unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac)
00118 {
00119 a += G(b, c, d) + x + ac;
00120 a = rotate_left(a, s) + b;
00121 }
00122 static inline void HH (unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac)
00123 {
00124 a += H(b, c, d) + x + ac;
00125 a = rotate_left(a, s) + b;
00126 }
00127 static inline void II (unsigned int& a, unsigned int b, unsigned int c, unsigned int d, unsigned int x, unsigned int s, unsigned int ac)
00128 {
00129 a += I(b, c, d) + x + ac;
00130 a = rotate_left(a, s) + b;
00131 }
00132 };
00133
00134 struct MD5_digest {
00135 unsigned long long val[2];
00136
00137 MD5_digest() {};
00138 MD5_digest( const std::string& msg ) {
00139 MD5 checkSum( (unsigned char*)(msg.c_str()), msg.length());
00140 checkSum.raw_digest( (unsigned char*) &val );
00141 }
00142
00143 bool operator< (const MD5_digest& rhs) const {
00144 if (val[0] == rhs.val[0]) {
00145 return (val[1] < rhs.val[1]);
00146 } else {
00147 return (val[0] < rhs.val[0]);
00148 }
00149 }
00150 };
00151
00152 #endif