00001 /*!@file Image/Hash.H hash/message-digest functions for Image objects */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/Hash.H $ 00035 // $Id: Hash.H 8296 2007-04-24 23:42:40Z rjpeters $ 00036 // 00037 00038 #ifndef IMAGE_HASH_H_DEFINED 00039 #define IMAGE_HASH_H_DEFINED 00040 00041 #include "Image/Image.H" 00042 #include "Util/Assert.H" 00043 #include "Util/Types.H" 00044 00045 #include <string> 00046 00047 template <class T> class PixRGB; 00048 00049 //! Helper function for Digest::format() 00050 std::string digestFormatHelper(const byte* buf, unsigned int n); 00051 00052 //! Helper function for Digest::fromString() 00053 void digestScanHelper(const std::string& s, byte* buf, unsigned int n); 00054 00055 //! Template message digest class represting a digest with N bytes. 00056 template <unsigned int N> 00057 struct Digest 00058 { 00059 // default ctor, dtor, copy-ctor, assignment operator OK 00060 00061 //! Comparison operator for sorting e.g. in std::set or std::map 00062 bool operator<(const Digest<N>& other) const 00063 { 00064 for (unsigned int i = 0; i < N; ++i) 00065 { 00066 if (this->buffer[i] < other.buffer[i]) 00067 return true; 00068 else if (this->buffer[i] > other.buffer[i]) 00069 return false; 00070 00071 // else, if this->buffer[i] == other.buffer[i] then we'll 00072 // continue into the next iteration and let the 00073 // greater-than/less-than decision be made by the next element 00074 } 00075 00076 // here, none of this->buffer was greater than other.buffer, nor 00077 // was it less than; ergo the two arrays are equal and since we 00078 // are computing strictly-less-than: 00079 return false; 00080 } 00081 00082 //! Return a string with N*2 hexadecimal chars representing the digest 00083 std::string asString() const 00084 { return digestFormatHelper(&buffer[0], N); } 00085 00086 //! Return an Nx1 Image containing the digest 00087 Image<byte> asImage() const 00088 { return Image<byte>(&buffer[0], N, 1); } 00089 00090 //! Pseudo-constructor to create a digest from a byte array 00091 /*! NOTE! This is NOT a message digest OF the byte array; rather we 00092 interpreting the bytes in the array as a message digest 00093 itself. This might be the case if e.g. a bunch of message 00094 digests have been saved to disk as byte images. */ 00095 static Digest<N> asDigest(const byte* d, const unsigned int len) 00096 { 00097 ASSERT(len == N); 00098 00099 Digest<N> result; 00100 for (size_t i = 0; i < N; ++i) 00101 { 00102 result.buffer[i] = d[i]; 00103 } 00104 00105 return result; 00106 } 00107 00108 //! Generate a digest by parsing hex digits from a string 00109 /*! @param s digest string must have exactly 2*N characters, each of 00110 which must be a valid hex digit (0-9, a-f, A-F) */ 00111 static Digest<N> fromString(const std::string& s) 00112 { 00113 Digest<N> result; 00114 digestScanHelper(s, &result.buffer[0], N); 00115 return result; 00116 } 00117 00118 byte buffer[N]; 00119 }; 00120 00121 // ############################################################ 00122 /*! @name Image hash digest functions 00123 00124 NOTE that these hash digest functions ARE NOT overloads -- that 00125 is, we don't have sha1sum() for Image<byte>, another sha1sum() for 00126 Image<float>, etc. That's because in the case of checksums, we 00127 want to be very clear that there shouldn't be any implicit 00128 conversions going on -- a checksum for an Image<byte> will be very 00129 different from the checksum for an Image<float> even if those two 00130 images contain logically identical pixels. To further avoid 00131 implicit conversions, the digest functions take a pointer, not a 00132 reference, to the Image object -- although there is an implicit 00133 conversion from Image<byte> to Image<float>, there is no 00134 conversion from Image<byte>* to Image<float>*. 00135 00136 NOTE also that these functions are NOT intended to be portable 00137 across machines with different endianness. However, the digests 00138 ARE reproducible across multiple runs on different machines with 00139 the same endianness. 00140 00141 In all of these functions, there is an optional void* parameter 00142 plus number of bytes, which, if non-null, will also be hashed into 00143 the digest. This affords the opportunity to hash some additional 00144 piece of information along with the image. For example, if you 00145 want to hash some integer 'x' along with an image, you could call 00146 md5byte(&img, &x, sizeof(int)). 00147 */ 00148 //@{ 00149 00150 //! Compute the 128-bit md5 digest of a byte image. 00151 Digest<16> md5byte(const Image<byte>* img, 00152 const void* extra = 0, size_t nextra = 0); 00153 00154 //! Compute the 128-bit md5 digest of a float image. 00155 Digest<16> md5float(const Image<float>* img, 00156 const void* extra = 0, size_t nextra = 0); 00157 00158 //! Compute the 128-bit md5 digest of an rgb image. 00159 Digest<16> md5rgb(const Image<PixRGB<byte> >* img, 00160 const void* extra = 0, size_t nextra = 0); 00161 00162 00163 //! Compute the 160-bit sha1 digest of a byte image. 00164 Digest<20> sha1byte(const Image<byte>* img, 00165 const void* extra = 0, size_t nextra = 0); 00166 00167 //! Compute the 160-bit sha1 digest of a float image. 00168 Digest<20> sha1float(const Image<float>* img, 00169 const void* extra = 0, size_t nextra = 0); 00170 00171 //! Compute the 160-bit sha1 digest of an rgb image. 00172 Digest<20> sha1rgb(const Image<PixRGB<byte> >* img, 00173 const void* extra = 0, size_t nextra = 0); 00174 00175 00176 //! Compute the 256-bit sha2 digest of a byte image. 00177 Digest<32> sha256byte(const Image<byte>* img, 00178 const void* extra = 0, size_t nextra = 0); 00179 00180 //! Compute the 256-bit sha2 digest of a float image. 00181 Digest<32> sha256float(const Image<float>* img, 00182 const void* extra = 0, size_t nextra = 0); 00183 00184 //! Compute the 256-bit sha2 digest of an rgb image. 00185 Digest<32> sha256rgb(const Image<PixRGB<byte> >* img, 00186 const void* extra = 0, size_t nextra = 0); 00187 00188 //@} 00189 00190 // ###################################################################### 00191 /* So things look consistent in everyone's emacs... */ 00192 /* Local Variables: */ 00193 /* indent-tabs-mode: nil */ 00194 /* End: */ 00195 00196 #endif // IMAGE_HASH_H_DEFINED