File indexing completed on 2026-04-09 07:49:33
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <string>
0015 #include <vector>
0016 #include <array>
0017 #include <sstream>
0018
0019 #if defined __APPLE__
0020
0021 # define COMMON_DIGEST_FOR_OPENSSL
0022 # include <CommonCrypto/CommonDigest.h>
0023 # define SHA1 CC_SHA1
0024
0025 #elif defined _MSC_VER
0026
0027 # include "md5.hh"
0028
0029 #elif __linux
0030
0031 # include <openssl/md5.h>
0032 # include <openssl/opensslv.h>
0033
0034 #endif
0035
0036 struct NP ;
0037
0038
0039 #if defined(__GNUC__) || defined(__clang__)
0040 #pragma GCC diagnostic push
0041 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0042 #endif
0043
0044 struct sdigest
0045 {
0046 static std::string Desc();
0047
0048 MD5_CTX ctx ;
0049 sdigest();
0050 void add( const std::string& str);
0051 void add( const char* str );
0052 void add( int i );
0053 void add( const char* buffer, int length);
0054 void add( const std::vector<unsigned char>& bytes );
0055
0056 std::string finalize() ;
0057 std::array<unsigned char,16> finalize_raw() ;
0058
0059
0060 static std::string Item(const NP* a, int i=-1, int j=-1, int k=-1, int l=-1, int m=-1, int o=-1);
0061 static std::array<unsigned char,16> ItemRaw(const NP* a, int i=-1, int j=-1, int k=-1, int l=-1, int m=-1, int o=-1);
0062
0063 static std::string Buf(const char* buffer, int length);
0064 static std::array<unsigned char,16> BufRaw(const char* buffer, int length);
0065 static void BufRaw_(unsigned char* digest_16, const char* buffer, int length);
0066
0067
0068 static std::string Int(int i);
0069 static std::string Path(const char* path, unsigned bufsize=8192 );
0070 static std::string Paths(std::vector<std::string>& paths, unsigned bufsize=8192 );
0071
0072
0073 static void Update( MD5_CTX& c, const std::string& str);
0074 static void Update( MD5_CTX& c, const char* str );
0075 static void Update( MD5_CTX& c, int i );
0076 static void Update( MD5_CTX& c, const char* buffer, int length);
0077
0078
0079 template<typename T> static void Update_(MD5_CTX& c, T* vv, size_t count );
0080
0081
0082 template<typename T> void add_( T* vv, size_t count );
0083
0084 static std::string DescRaw( unsigned char* digest16 );
0085
0086 static std::string Finalize(MD5_CTX& c);
0087 static std::array<unsigned char,16> FinalizeRaw(MD5_CTX& c);
0088
0089 static void FinalizeRaw_(unsigned char* digest_16, MD5_CTX& c );
0090
0091
0092
0093 };
0094
0095
0096 inline std::string sdigest::Desc()
0097 {
0098 std::stringstream ss ;
0099 #if OPENSSL_VERSION_NUMBER == 0x100020bfL
0100 ss << "OPENSSL_VERSION_NUMBER == 0x100020bfL" << std::endl ;
0101 #elif OPENSSL_VERSION_NUMBER > 0x100020bfL
0102 ss << "OPENSSL_VERSION_NUMBER > 0x100020bfL" << std::endl ;
0103 #elif OPENSSL_VERSION_NUMBER < 0x100020bfL
0104 ss << "OPENSSL_VERSION_NUMBER < 0x100020bfL" << std::endl ;
0105 #endif
0106
0107 #if __linux
0108 ss << "Linux : OPENSSL_VERSION_NUMBER is 0x" << std::hex << OPENSSL_VERSION_NUMBER << std::dec << std::endl ;
0109 #endif
0110
0111 std::string s = ss.str();
0112 return s ;
0113 }
0114
0115
0116 inline sdigest::sdigest(){ MD5_Init(&ctx); }
0117 inline void sdigest::add( const std::string& str){ Update(ctx, str) ; }
0118 inline void sdigest::add( const char* str ){ Update(ctx, str) ; }
0119 inline void sdigest::add( int i ){ Update(ctx, i ) ; }
0120 inline void sdigest::add( const char* str, int length ){ Update(ctx, str, length ) ; }
0121 inline void sdigest::add( const std::vector<unsigned char>& bytes ){ Update(ctx, (char*)bytes.data(), bytes.size() ); }
0122
0123 inline std::string sdigest::finalize(){ return Finalize(ctx) ; }
0124 inline std::array<unsigned char,16> sdigest::finalize_raw(){ return FinalizeRaw(ctx) ; }
0125
0126
0127
0128 #include "NP.hh"
0129
0130 inline std::string sdigest::Item( const NP* a, int i, int j, int k, int l, int m, int o )
0131 {
0132 const char* start = nullptr ;
0133 NP::INT num_bytes = 0 ;
0134 a->itembytes_(&start, num_bytes, i, j, k, l, m, o );
0135 assert( start && num_bytes > 0 );
0136 return Buf( start, num_bytes );
0137 }
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149 inline std::array<unsigned char,16> sdigest::ItemRaw( const NP* a, int i, int j, int k, int l, int m, int o )
0150 {
0151 const char* start = nullptr ;
0152 NP::INT num_bytes = 0 ;
0153 a->itembytes_(&start, num_bytes, i, j, k, l, m, o );
0154 assert( start && num_bytes > 0 );
0155 return BufRaw( start, num_bytes );
0156 }
0157
0158
0159 inline std::string sdigest::Buf(const char* buffer, int length)
0160 {
0161 MD5_CTX c;
0162 MD5_Init(&c);
0163 Update(c, buffer, length);
0164 return Finalize(c);
0165 }
0166 inline std::array<unsigned char,16> sdigest::BufRaw(const char* buffer, int length)
0167 {
0168 MD5_CTX c;
0169 MD5_Init(&c);
0170 Update(c, buffer, length);
0171 return FinalizeRaw(c);
0172 }
0173
0174 inline void sdigest::BufRaw_(unsigned char* digest_16, const char* buffer, int length)
0175 {
0176 MD5_CTX c;
0177 MD5_Init(&c);
0178 Update(c, buffer, length);
0179 FinalizeRaw_(digest_16, c);
0180 }
0181
0182
0183
0184
0185 inline std::string sdigest::Int(int i)
0186 {
0187 MD5_CTX c;
0188 MD5_Init(&c);
0189 Update(c, i);
0190 return Finalize(c);
0191 }
0192
0193
0194 inline std::string sdigest::Path(const char* path, unsigned bufsize )
0195 {
0196
0197
0198 FILE* fp = fopen(path, "rb");
0199 if (fp == NULL)
0200 {
0201 std::cerr << "failed to open path [" << path << "]" << std::endl ;
0202 return "" ;
0203 }
0204
0205 sdigest dig ;
0206 char* data = new char[bufsize] ;
0207 int bytes ;
0208 while ((bytes = fread (data, 1, bufsize, fp)) != 0) dig.add(data, bytes);
0209
0210 delete[] data ;
0211
0212 std::string out = dig.finalize();
0213
0214 return out ;
0215 }
0216
0217 inline std::string sdigest::Paths(std::vector<std::string>& paths, unsigned bufsize )
0218 {
0219 sdigest dig ;
0220 char* data = new char[bufsize] ;
0221
0222 int num_paths = paths.size();
0223 for(int i=0 ; i < num_paths ; i++)
0224 {
0225 const char* path = paths[i].c_str();
0226
0227 FILE* fp = fopen(path, "rb");
0228 if (fp == NULL)
0229 {
0230 std::cerr
0231 << "sdigest::Paths"
0232 << " failed to open"
0233 << " path [" << path << "]\n"
0234 ;
0235 continue ;
0236 }
0237
0238 int bytes ;
0239 while ((bytes = fread (data, 1, bufsize, fp)) != 0) dig.add(data, bytes);
0240
0241 fclose(fp);
0242 }
0243
0244 delete[] data ;
0245
0246 std::string out = dig.finalize();
0247
0248 return out ;
0249 }
0250
0251
0252
0253
0254
0255 inline void sdigest::Update(MD5_CTX& c, const std::string& str)
0256 {
0257 Update(c, str.c_str() );
0258 }
0259
0260 inline void sdigest::Update(MD5_CTX& c, const char* str )
0261 {
0262 Update( c, (char*)str, strlen(str) );
0263 }
0264
0265 inline void sdigest::Update(MD5_CTX& c, int i )
0266 {
0267 Update( c, (char*)&i, sizeof(int) );
0268 }
0269
0270 inline void sdigest::Update(MD5_CTX& c, const char* buffer, int length)
0271 {
0272 const int blocksize = 512 ;
0273 while (length > 0)
0274 {
0275 if (length > blocksize) {
0276 MD5_Update(&c, buffer, blocksize);
0277 } else {
0278 MD5_Update(&c, buffer, length);
0279 }
0280 length -= blocksize ;
0281 buffer += blocksize ;
0282 }
0283 }
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298 template<typename T>
0299 inline void sdigest::Update_(MD5_CTX& c, T* vv, size_t count )
0300 {
0301 Update( c, (char*)vv, sizeof(T)*count );
0302 }
0303
0304 template<typename T>
0305 inline void sdigest::add_( T* vv, size_t count ){ Update_<T>(ctx, vv, count ); }
0306
0307
0308
0309 inline std::string sdigest::DescRaw( unsigned char* digest16 )
0310 {
0311 char buf[32+1] ;
0312 for (int n = 0; n < 16; ++n)
0313 std::snprintf(&buf[2 * n], 3, "%02x", (unsigned int)digest16[n]);
0314 buf[32] = '\0' ;
0315 return std::string(buf, buf + 32);
0316 }
0317
0318
0319 inline std::string sdigest::Finalize(MD5_CTX& c)
0320 {
0321 unsigned char digest[16];
0322 MD5_Final(digest, &c);
0323
0324
0325
0326 char buf[32+1] ;
0327 for (int n = 0; n < 16; ++n)
0328 std::snprintf(&buf[2 * n], 3, "%02x", (unsigned int)digest[n]);
0329 buf[32] = '\0' ;
0330
0331 return std::string(buf, buf + 32);
0332 }
0333
0334 inline std::array<unsigned char,16> sdigest::FinalizeRaw(MD5_CTX& c)
0335 {
0336 unsigned char digest[16];
0337 MD5_Final(digest, &c);
0338
0339 std::array<unsigned char, 16> result;
0340 std::copy(digest, digest + 16, result.begin());
0341 return result;
0342 }
0343
0344 inline void sdigest::FinalizeRaw_(unsigned char* digest_16, MD5_CTX& c )
0345 {
0346 MD5_Final(digest_16, &c );
0347 }
0348
0349
0350
0351
0352 #if defined(__GNUC__) || defined(__clang__)
0353 #pragma GCC diagnostic pop
0354 #endif
0355