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
00070 std::string MD5Result::toString() const
00071 {
00072 std::ostringstream os;
00073 os << std::hex << std::setfill('0');
00074 for (size_t i = 0 ; i < sizeof(bytes) ; ++i)
00075 os << std::setw(2) << static_cast<int>(bytes[i]);
00076 return os.str();
00077 }
00078
00079 std::string MD5Result::compactForm() const
00080 {
00081
00082
00083
00084 const char* p = reinterpret_cast<const char*>(&bytes[0]);
00085 return std::string(p, p+sizeof(bytes));
00086 }
00087
00088 void MD5Result::fromHexifiedString(std::string const& hexy)
00089 {
00090 switch (hexy.size())
00091 {
00092 case 0:
00093 {
00094 set_to_default(*this);
00095 }
00096 break;
00097 case 32:
00098 {
00099 std::string::const_iterator it = hexy.begin();
00100 for (size_t i = 0; i != 16; ++i)
00101 {
00102
00103 bytes[i] = ( unhexify(*it++) << 4 );
00104
00105 bytes[i] += ( unhexify(*it++) );
00106 }
00107 }
00108 break;
00109 default:
00110 {
00111
00112 throw edm::Exception(edm::errors::LogicError)
00113 << "String of illegal length: "
00114 << hexy.size()
00115 << " given to MD5Result::fromHexifiedString";
00116 }
00117 }
00118 }
00119
00120 bool MD5Result::isValid() const
00121 {
00122 return (*this != invalidResult());
00123 }
00124
00125 bool operator==(MD5Result const& a, MD5Result const& b)
00126 {
00127 return std::equal(a.bytes, a.bytes+sizeof(a.bytes), b.bytes);
00128 }
00129
00130
00131 bool operator< (MD5Result const& a, MD5Result const& b)
00132 {
00133 return std::lexicographical_compare(a.bytes,
00134 a.bytes+sizeof(a.bytes),
00135 b.bytes,
00136 b.bytes+sizeof(b.bytes));
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146 Digest::Digest() :
00147 state_()
00148 {
00149 md5_init(&state_);
00150 }
00151
00152 Digest::Digest(std::string const& s) :
00153 state_()
00154 {
00155 md5_init(&state_);
00156 this->append(s);
00157 }
00158
00159 void Digest::append(std::string const& s)
00160 {
00161 const md5_byte_t* data = reinterpret_cast<const md5_byte_t*>(s.data());
00162 md5_append(&state_, const_cast<md5_byte_t*>(data), s.size());
00163 }
00164
00165 MD5Result Digest::digest() const
00166 {
00167 MD5Result aDigest;
00168 md5_finish(&state_, aDigest.bytes);
00169 return aDigest;
00170 }
00171 }