jigdo API
Last update by Admin on 2010-05-23
util/md5sum.hh
Go to the documentation of this file.00001 /* $Id: md5sum.hh,v 1.2 2003/09/27 21:31:04 atterer Exp $ -*- C++ -*- 00002 __ _ 00003 |_) /| Copyright (C) 2000-2004 | richard@ 00004 | \/¯| Richard Atterer | atterer.net 00005 ¯ '` ¯ 00006 "Ported" to C++ by RA. Actual MD5 code taken from glibc 00007 00008 This program is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License, version 2. See 00010 the file COPYING for details. 00011 00012 */ 00018 #ifndef MD5SUM_HH 00019 #define MD5SUM_HH 00020 00021 #ifndef INLINE 00022 # ifdef NOINLINE 00023 # define INLINE 00024 # else 00025 # define INLINE inline 00026 # endif 00027 #endif 00028 00029 #include <config.h> 00030 00031 #include <cstdlib> 00032 #include <iosfwd> 00033 #include <string> 00034 00035 #include <bstream.hh> 00036 #include <debug.hh> 00037 #include <md5sum.fh> 00038 //______________________________________________________________________ 00039 00047 class MD5 { 00048 public: 00049 MD5() { } 00050 inline MD5(const MD5Sum& md); 00052 byte sum[16]; 00055 operator byte*() { return sum; } 00056 operator const byte*() const { return sum; } 00058 inline MD5& operator=(const MD5Sum& md); 00059 inline bool operator<(const MD5& x) const; 00061 inline MD5& clear(); 00063 string toString() const; 00064 00065 template<class Iterator> 00066 inline Iterator serialize(Iterator i) const; 00067 template<class ConstIterator> 00068 inline ConstIterator unserialize(ConstIterator i); 00069 inline size_t serialSizeOf() const { return 16; } 00070 00071 // Default copy ctor 00072 private: 00073 bool operator_less2(const MD5& x) const; 00074 static const byte zero[16]; 00075 }; 00076 00077 inline bool operator==(const MD5& a, const MD5& b); 00078 inline bool operator!=(const MD5& a, const MD5& b) { return !(a == b); } 00079 00081 INLINE ostream& operator<<(ostream& s, const MD5& r); 00082 //______________________________________________________________________ 00083 00089 class MD5Sum { 00090 friend class MD5; 00091 public: 00092 class ProgressReporter; 00093 00095 inline MD5Sum(); 00097 MD5Sum(const MD5Sum& md); 00098 ~MD5Sum() { delete p; } 00100 MD5Sum& operator=(const MD5Sum& md); 00104 inline bool operator==(const MD5Sum& md) const; 00105 inline bool operator!=(const MD5Sum& md) const; 00106 inline bool operator==(const MD5& md) const { return sum == md; } 00107 inline bool operator!=(const MD5& md) const { return sum != md; } 00111 inline MD5Sum& reset(); 00114 inline MD5Sum& update(const byte* mem, size_t len); 00116 inline MD5Sum& update(byte x) { update(&x, 1); return *this; } 00120 inline MD5Sum& finish(); 00125 inline MD5Sum& finishForReuse(); 00128 inline MD5Sum& abort(); 00131 inline const byte* digest() const; 00132 00134 INLINE string toString() const; 00135 00142 uint64 updateFromStream(bistream& s, uint64 size, 00143 size_t bufSize = 128*1024, ProgressReporter& pr = noReport); 00144 00145 /* Serializing an MD5Sum is only allowed after finish(). The 00146 serialization is compatible with that of MD5. */ 00147 template<class Iterator> 00148 inline Iterator serialize(Iterator i) const; 00149 template<class ConstIterator> 00150 inline ConstIterator unserialize(ConstIterator i); 00151 inline size_t serialSizeOf() const { return sum.serialSizeOf(); } 00152 00153 private: 00154 struct md5_ctx { 00155 uint32 A, B, C, D; 00156 uint32 total[2]; 00157 uint32 buflen; 00158 char buffer[128] __attribute__ ((__aligned__ (__alignof__ (uint32)))); 00159 }; 00160 00162 static ProgressReporter noReport; 00163 00164 // These functions are the original glibc API 00165 static void md5_init_ctx(md5_ctx* ctx); 00166 static void md5_process_bytes(const void* buffer, size_t len, 00167 struct md5_ctx* ctx); 00168 static byte* md5_finish_ctx(struct md5_ctx* ctx, byte* resbuf); 00169 static byte* md5_read_ctx(const md5_ctx *ctx, byte* resbuf); 00170 static void md5_process_block(const void* buffer, size_t len, 00171 md5_ctx* ctx); 00172 MD5 sum; 00173 struct md5_ctx* p; // null once MD creation is finished 00174 00175 # if DEBUG 00176 /* After finish(ForReuse)(), must call reset() before the next 00177 update(). OTOH, must only call digest() after finish(). Enforce 00178 this rule by keeping track of the state. */ 00179 bool finished; 00180 # endif 00181 }; 00182 00183 inline bool operator==(const MD5& a, const MD5Sum& b) { return b == a; } 00184 inline bool operator!=(const MD5& a, const MD5Sum& b) { return b != a; } 00185 00187 INLINE ostream& operator<<(ostream& s, const MD5Sum& r); 00188 //______________________________________________________________________ 00189 00192 class MD5Sum::ProgressReporter { 00193 public: 00194 virtual ~ProgressReporter() { } 00196 virtual void error(const string& message); 00198 virtual void info(const string& message); 00200 virtual void readingMD5(uint64 offInStream, uint64 size); 00201 }; 00202 //______________________________________________________________________ 00203 00204 bool MD5Sum::operator==(const MD5Sum& md) const { 00205 # if DEBUG 00206 Paranoid(this->finished && md.finished); 00207 # endif 00208 return sum == md.sum; 00209 } 00210 bool MD5Sum::operator!=(const MD5Sum& md) const { 00211 # if DEBUG 00212 Paranoid(this->finished && md.finished); 00213 # endif 00214 return sum != md.sum; 00215 } 00216 00217 MD5Sum::MD5Sum() { 00218 p = new md5_ctx(); 00219 md5_init_ctx(p); 00220 # if DEBUG 00221 finished = false; 00222 # endif 00223 } 00224 00225 MD5Sum& MD5Sum::reset() { 00226 if (p == 0) p = new md5_ctx(); 00227 md5_init_ctx(p); 00228 # if DEBUG 00229 finished = false; 00230 # endif 00231 return *this; 00232 } 00233 00234 MD5Sum& MD5Sum::update(const byte* mem, size_t len) { 00235 Paranoid(p != 0); 00236 # if DEBUG 00237 Paranoid(!finished); // Don't forget to call reset() before update() 00238 # endif 00239 md5_process_bytes(mem, len, p); 00240 return *this; 00241 } 00242 00243 MD5Sum& MD5Sum::finish() { 00244 Paranoid(p != 0 ); 00245 md5_finish_ctx(p, sum); 00246 delete p; 00247 p = 0; 00248 # if DEBUG 00249 finished = true; 00250 # endif 00251 return *this; 00252 } 00253 00254 MD5Sum& MD5Sum::finishForReuse() { 00255 Paranoid(p != 0 ); 00256 md5_finish_ctx(p, sum); 00257 # if DEBUG 00258 finished = true; 00259 # endif 00260 return *this; 00261 } 00262 00263 MD5Sum& MD5Sum::abort() { 00264 delete p; 00265 p = 0; 00266 # if DEBUG 00267 finished = false; 00268 # endif 00269 return *this; 00270 } 00271 00272 const byte* MD5Sum::digest() const { 00273 # if DEBUG 00274 Paranoid(finished); // Call finish() first 00275 # endif 00276 return sum.sum; 00277 } 00278 00279 template<class Iterator> 00280 inline Iterator MD5Sum::serialize(Iterator i) const { 00281 # if DEBUG 00282 Paranoid(finished ); // Call finish() first 00283 # endif 00284 return sum.serialize(i); 00285 } 00286 template<class ConstIterator> 00287 inline ConstIterator MD5Sum::unserialize(ConstIterator i) { 00288 # if DEBUG 00289 finished = true; 00290 # endif 00291 return sum.unserialize(i); 00292 } 00293 //____________________ 00294 00295 MD5& MD5::operator=(const MD5Sum& md) { 00296 # if DEBUG 00297 Paranoid(md.finished); // Call finish() first 00298 # endif 00299 *this = md.sum; 00300 return *this; 00301 } 00302 00303 bool MD5::operator<(const MD5& x) const { 00304 if (sum[0] < x.sum[0]) return true; 00305 if (sum[0] > x.sum[0]) return false; 00306 return operator_less2(x); 00307 } 00308 00309 // inline bool operator<(const MD5& a, const MD5& b) { 00310 // return a.operator<(b); 00311 // } 00312 00313 MD5::MD5(const MD5Sum& md) { *this = md.sum; } 00314 00315 bool operator==(const MD5& a, const MD5& b) { 00316 // How portable is this? 00317 return memcmp(a.sum, b.sum, 16 * sizeof(byte)) == 0; 00318 # if 0 00319 return a.sum[0] == b.sum[0] && a.sum[1] == b.sum[1] 00320 && a.sum[2] == b.sum[2] && a.sum[3] == b.sum[3] 00321 && a.sum[4] == b.sum[4] && a.sum[5] == b.sum[5] 00322 && a.sum[6] == b.sum[6] && a.sum[7] == b.sum[7] 00323 && a.sum[8] == b.sum[8] && a.sum[9] == b.sum[9] 00324 && a.sum[10] == b.sum[10] && a.sum[11] == b.sum[11] 00325 && a.sum[12] == b.sum[12] && a.sum[13] == b.sum[13] 00326 && a.sum[14] == b.sum[14] && a.sum[15] == b.sum[15]; 00327 # endif 00328 } 00329 00330 MD5& MD5::clear() { 00331 byte* x = sum; 00332 *x++ = 0; *x++ = 0; *x++ = 0; *x++ = 0; 00333 *x++ = 0; *x++ = 0; *x++ = 0; *x++ = 0; 00334 *x++ = 0; *x++ = 0; *x++ = 0; *x++ = 0; 00335 *x++ = 0; *x++ = 0; *x++ = 0; *x++ = 0; 00336 return *this; 00337 } 00338 00339 template<class Iterator> 00340 inline Iterator MD5::serialize(Iterator i) const { 00341 for (int j = 0; j < 16; ++j) { *i = sum[j]; ++i; } 00342 return i; 00343 } 00344 template<class ConstIterator> 00345 inline ConstIterator MD5::unserialize(ConstIterator i) { 00346 for (int j = 0; j < 16; ++j) { sum[j] = *i; ++i; } 00347 return i; 00348 } 00349 00350 #ifndef NOINLINE 00351 # include <md5sum.ih> /* NOINLINE */ 00352 #endif 00353 00354 #endif
Generated on Tue Sep 23 14:27:42 2008 for jigdo by
