Go to the documentation of this file.00001 #include <iomanip>
00002 #include <sstream>
00003
00004 #include "FWCore/Utilities/interface/EDMException.h"
00005 #include "FWCore/Utilities/interface/Digest.h"
00006
00007 namespace cms
00008 {
00009 namespace
00010 {
00011 MD5Result const& invalidResult()
00012 {
00013 static const MD5Result val;
00014 return val;
00015 }
00016
00017 char unhexify(char hexed)
00018 {
00019 switch (hexed)
00020 {
00021 case '0': case '1': case '2': case '3': case '4':
00022 case '5': case '6': case '7': case '8': case '9':
00023 return hexed - '0';
00024 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
00025 return hexed - 'a' + 10;
00026 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
00027 return hexed - 'A' + 10;
00028 default:
00029 throw edm::Exception(edm::errors::LogicError)
00030 << "Non-hex character in Hash "
00031 << "Please report this to the core framework developers";
00032 }
00033
00034
00035 return '\0';
00036 }
00037 }
00038
00039
00040
00041
00042
00043
00044 void set_to_default(MD5Result& val)
00045 {
00046 val.bytes[0] = 0xd4;
00047 val.bytes[1] = 0x1d;
00048 val.bytes[2] = 0x8c;
00049 val.bytes[3] = 0xd9;
00050 val.bytes[4] = 0x8f;
00051 val.bytes[5] = 0x00;
00052 val.bytes[6] = 0xb2;
00053 val.bytes[7] = 0x04;
00054 val.bytes[8] = 0xe9;
00055 val.bytes[9] = 0x80;
00056 val.bytes[10] = 0x09;
00057 val.bytes[11] = 0x98;
00058 val.bytes[12] = 0xec;
00059 val.bytes[13] = 0xf8;
00060 val.bytes[14] = 0x42;
00061 val.bytes[15] = 0x7e;
00062 }
00063
00064 MD5Result::MD5Result()
00065 {
00066 set_to_default(*this);
00067 }
00068
00069 static const char * s_hexValues =
00070 "000102030405060708090a0b0c0d0e0f"
00071 "101112131415161718191a1b1c1d1e1f"
00072 "202122232425262728292a2b2c2d2e2f"
00073 "303132333435363738393a3b3c3d3e3f"
00074 "404142434445464748494a4b4c4d4e4f"
00075 "505152535455565758595a5b5c5d5e5f"
00076 "606162636465666768696a6b6c6d6e6f"
00077 "707172737475767778797a7b7c7d7e7f"
00078 "808182838485868788898a8b8c8d8e8f"
00079 "909192939495969798999a9b9c9d9e9f"
00080 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
00081 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
00082 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
00083 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
00084 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
00085 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
00086
00087 std::string MD5Result::toString() const
00088 {
00089 char buf[16*2];
00090 char* pBuf=buf;
00091 for(unsigned int i=0; i<sizeof(bytes);++i){
00092 const char* p = s_hexValues+2*bytes[i];
00093 *pBuf = *p;
00094 ++pBuf;
00095 ++p;
00096 *pBuf=*p;
00097 ++pBuf;
00098 }
00099 return std::string(buf, sizeof(buf));
00100 }
00101
00102 std::string MD5Result::compactForm() const
00103 {
00104
00105
00106
00107 const char* p = reinterpret_cast<const char*>(&bytes[0]);
00108 return std::string(p, p+sizeof(bytes));
00109 }
00110
00111 void MD5Result::fromHexifiedString(std::string const& hexy)
00112 {
00113 switch (hexy.size())
00114 {
00115 case 0:
00116 {
00117 set_to_default(*this);
00118 }
00119 break;
00120 case 32:
00121 {
00122 std::string::const_iterator it = hexy.begin();
00123 for (size_t i = 0; i != 16; ++i)
00124 {
00125
00126 bytes[i] = ( unhexify(*it++) << 4 );
00127
00128 bytes[i] += ( unhexify(*it++) );
00129 }
00130 }
00131 break;
00132 default:
00133 {
00134
00135 throw edm::Exception(edm::errors::LogicError)
00136 << "String of illegal length: "
00137 << hexy.size()
00138 << " given to MD5Result::fromHexifiedString";
00139 }
00140 }
00141 }
00142
00143 bool MD5Result::isValid() const
00144 {
00145 return (*this != invalidResult());
00146 }
00147
00148 bool operator==(MD5Result const& a, MD5Result const& b)
00149 {
00150 return std::equal(a.bytes, a.bytes+sizeof(a.bytes), b.bytes);
00151 }
00152
00153
00154 bool operator< (MD5Result const& a, MD5Result const& b)
00155 {
00156 return std::lexicographical_compare(a.bytes,
00157 a.bytes+sizeof(a.bytes),
00158 b.bytes,
00159 b.bytes+sizeof(b.bytes));
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169 Digest::Digest() :
00170 state_()
00171 {
00172 md5_init(&state_);
00173 }
00174
00175 Digest::Digest(std::string const& s) :
00176 state_()
00177 {
00178 md5_init(&state_);
00179 this->append(s);
00180 }
00181
00182 void Digest::append(std::string const& s)
00183 {
00184 const md5_byte_t* data = reinterpret_cast<const md5_byte_t*>(s.data());
00185 md5_append(&state_, const_cast<md5_byte_t*>(data), s.size());
00186 }
00187
00188 void Digest::append(const char *s, size_t size)
00189 {
00190 const md5_byte_t* data = reinterpret_cast<const md5_byte_t*>(s);
00191 md5_append(&state_, const_cast<md5_byte_t*>(data), size);
00192 }
00193
00194 MD5Result Digest::digest() const
00195 {
00196 MD5Result aDigest;
00197 md5_finish(&state_, aDigest.bytes);
00198 return aDigest;
00199 }
00200 }