File indexing completed on 2024-11-25 02:29:37
0001 #include <iomanip>
0002 #include <sstream>
0003
0004 #include "FWCore/Utilities/interface/EDMException.h"
0005 #include "FWCore/Utilities/interface/Digest.h"
0006
0007 namespace cms {
0008 namespace {
0009 MD5Result const& invalidResult() {
0010 static const MD5Result val;
0011 return val;
0012 }
0013
0014 char unhexify(char hexed) {
0015 switch (hexed) {
0016 case '0':
0017 case '1':
0018 case '2':
0019 case '3':
0020 case '4':
0021 case '5':
0022 case '6':
0023 case '7':
0024 case '8':
0025 case '9':
0026 return hexed - '0';
0027 case 'a':
0028 case 'b':
0029 case 'c':
0030 case 'd':
0031 case 'e':
0032 case 'f':
0033 return hexed - 'a' + 10;
0034 case 'A':
0035 case 'B':
0036 case 'C':
0037 case 'D':
0038 case 'E':
0039 case 'F':
0040 return hexed - 'A' + 10;
0041 default:
0042 throw edm::Exception(edm::errors::LogicError) << "Non-hex character in Hash "
0043 << "Please report this to the core framework developers";
0044 }
0045
0046
0047 return '\0';
0048 }
0049 }
0050
0051
0052
0053
0054
0055
0056 void set_to_default(MD5Result& val) {
0057 val.bytes[0] = 0xd4;
0058 val.bytes[1] = 0x1d;
0059 val.bytes[2] = 0x8c;
0060 val.bytes[3] = 0xd9;
0061 val.bytes[4] = 0x8f;
0062 val.bytes[5] = 0x00;
0063 val.bytes[6] = 0xb2;
0064 val.bytes[7] = 0x04;
0065 val.bytes[8] = 0xe9;
0066 val.bytes[9] = 0x80;
0067 val.bytes[10] = 0x09;
0068 val.bytes[11] = 0x98;
0069 val.bytes[12] = 0xec;
0070 val.bytes[13] = 0xf8;
0071 val.bytes[14] = 0x42;
0072 val.bytes[15] = 0x7e;
0073 }
0074
0075 MD5Result::MD5Result() { set_to_default(*this); }
0076
0077 static const char* s_hexValues =
0078 "000102030405060708090a0b0c0d0e0f"
0079 "101112131415161718191a1b1c1d1e1f"
0080 "202122232425262728292a2b2c2d2e2f"
0081 "303132333435363738393a3b3c3d3e3f"
0082 "404142434445464748494a4b4c4d4e4f"
0083 "505152535455565758595a5b5c5d5e5f"
0084 "606162636465666768696a6b6c6d6e6f"
0085 "707172737475767778797a7b7c7d7e7f"
0086 "808182838485868788898a8b8c8d8e8f"
0087 "909192939495969798999a9b9c9d9e9f"
0088 "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
0089 "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
0090 "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
0091 "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
0092 "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
0093 "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
0094
0095 std::string MD5Result::toString() const {
0096 std::array<char, 16 * 2> buf;
0097 char* pBuf = buf.begin();
0098 for (auto b : bytes) {
0099 const char* p = s_hexValues + 2 * b;
0100 *pBuf = *p;
0101 ++pBuf;
0102 ++p;
0103 *pBuf = *p;
0104 ++pBuf;
0105 }
0106 return std::string(buf.begin(), buf.end());
0107 }
0108
0109 std::string MD5Result::compactForm() const {
0110
0111
0112
0113 const char* p = reinterpret_cast<const char*>(bytes.data());
0114 return std::string(p, p + bytes.size());
0115 }
0116
0117 void MD5Result::fromHexifiedString(std::string_view hexy) {
0118 switch (hexy.size()) {
0119 case 0: {
0120 set_to_default(*this);
0121 } break;
0122 case 32: {
0123 auto it = hexy.cbegin();
0124 for (size_t i = 0; i != 16; ++i) {
0125
0126 bytes[i] = (unhexify(*it++) << 4);
0127
0128 bytes[i] += (unhexify(*it++));
0129 }
0130 } break;
0131 default: {
0132
0133 throw edm::Exception(edm::errors::LogicError)
0134 << "String of illegal length: " << hexy.size() << " given to MD5Result::fromHexifiedString";
0135 }
0136 }
0137 }
0138
0139 bool MD5Result::isValid() const { return (*this != invalidResult()); }
0140
0141 bool operator==(MD5Result const& a, MD5Result const& b) {
0142 return std::equal(a.bytes.begin(), a.bytes.end(), b.bytes.begin());
0143 }
0144
0145 bool operator<(MD5Result const& a, MD5Result const& b) {
0146 return std::lexicographical_compare(a.bytes.begin(), a.bytes.end(), b.bytes.begin(), b.bytes.end());
0147 }
0148
0149
0150
0151
0152
0153
0154 Digest::Digest() : state_() { md5_init(&state_); }
0155
0156 Digest::Digest(std::string const& s) : state_() {
0157 md5_init(&state_);
0158 this->append(s);
0159 }
0160
0161 Digest::Digest(std::string_view v) : state_() {
0162 md5_init(&state_);
0163 this->append(v);
0164 }
0165
0166 Digest::Digest(const char* s) : state_() {
0167 md5_init(&state_);
0168 this->append(s, strlen(s));
0169 }
0170
0171 void Digest::append(std::string const& s) {
0172 const md5_byte_t* data = reinterpret_cast<const md5_byte_t*>(s.data());
0173 md5_append(&state_, const_cast<md5_byte_t*>(data), s.size());
0174 }
0175
0176 void Digest::append(std::string_view v) {
0177 const md5_byte_t* data = reinterpret_cast<const md5_byte_t*>(v.data());
0178 md5_append(&state_, const_cast<md5_byte_t*>(data), v.size());
0179 }
0180
0181 void Digest::append(const char* s, size_t size) {
0182 const md5_byte_t* data = reinterpret_cast<const md5_byte_t*>(s);
0183 md5_append(&state_, const_cast<md5_byte_t*>(data), size);
0184 }
0185
0186 MD5Result Digest::digest() {
0187 MD5Result aDigest;
0188 md5_finish(&state_, aDigest.bytes.data());
0189 return aDigest;
0190 }
0191 }