Upstream tarball 9613
[amule.git] / src / MD4Hash.h
blobc181b77669ec5af4783fc4901eec96cfd8151019
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 //
6 // Any parts of this program derived from the xMule, lMule or eMule project,
7 // or contributed by third-party developers are copyrighted by their
8 // respective authors.
9 //
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #ifndef CMD4HASH_H
26 #define CMD4HASH_H
29 #include "ArchSpecific.h" // Needed for Raw{Peek,Poke}UInt64()
31 #include "kademlia/utils/UInt128.h" // Needed for CUInt128
33 #include <common/MuleDebug.h> // Needed for MULE_VALIDATE_PARAMS
35 #ifdef USE_WX_EXTENSIONS
36 #include <common/StringFunctions.h>
37 #endif
39 #include <string>
42 const size_t MD4HASH_LENGTH = 16;
45 /**
46 * Container-class for the MD4 hashes used in aMule.
48 * This is a safe representation of the MD4 hashes used in aMule. By transparently
49 * wrapping the char array used to store the hash, we get the advantages of
50 * assigment, equality and non-equality operators, plus other nifty features.
52 * Please remember that the hashes are arrays with length 16 WITHOUT a zero-terminator!
54 class CMD4Hash
56 public:
57 /**
58 * Default constructor.
60 * The default constructor creates an empty hash of length 16.
61 * Each field of the char array has an initial value of zero.
63 CMD4Hash() {
64 Clear();
67 /**
68 * Create a CMD4Hash from a CUInt128
70 * @param hash The 128 bits integer to be used.
73 CMD4Hash(const Kademlia::CUInt128& hash) {
74 byte transitional_array[MD4HASH_LENGTH];
75 hash.ToByteArray(transitional_array);
76 SetHash(transitional_array);
79 ~CMD4Hash() {
82 /**
83 * Cast a unsigned char array to a CMD4Hash.
85 * @param hash The array to be cast.
87 * Please note that the array must either be a NULL pointer or be at least
88 * 16 chars long, not including any possible zero-terminator!
90 explicit CMD4Hash(const unsigned char hash[]) {
91 SetHash(hash);
94 /**
95 * Equality operator.
97 * Returns true if all fields of both hashes are the same.
99 bool operator == (const CMD4Hash& other_hash) const {
100 return (
101 ( RawPeekUInt64( m_hash ) == RawPeekUInt64( other_hash.m_hash ) ) &&
102 ( RawPeekUInt64( m_hash + 8 ) == RawPeekUInt64( other_hash.m_hash + 8 ) )
107 * Non-equality operator
109 * Returns true if there is any difference between the two hashes.
111 bool operator != (const CMD4Hash& other_hash) const {
112 return !(*this == other_hash);
116 * Less than operator.
118 * @return True if the hash is less than other_hash, false otherwise.
120 * The purpose of this function is to enable the usage of CMD4Hashes in
121 * sorted STL containers like std::map.
123 bool operator < (const CMD4Hash& other_hash) const {
124 for ( size_t i = 0; i < MD4HASH_LENGTH; ++i ) {
125 if ( m_hash[i] < other_hash.m_hash[i] ) {
126 return true;
127 } else if ( other_hash.m_hash[i] < m_hash[i] ) {
128 return false;
132 return false;
137 * Returns true if the hash is empty.
139 * @return True if all fields are zero, false otherwise.
141 * This functions checks the contents of the hash and returns true
142 * only if each field of the array contains the value zero.
143 * To achive an empty hash, the function Clear() can be used.
145 bool IsEmpty() const {
146 return (
147 !RawPeekUInt64( m_hash ) &&
148 !RawPeekUInt64( m_hash + 8 )
152 /**
153 * Resets the contents of the hash.
155 * This functions sets the value of each field of the hash to zero.
156 * IsEmpty() will return true after a call to this function.
158 void Clear() {
159 RawPokeUInt64( m_hash, 0 );
160 RawPokeUInt64( m_hash + 8, 0 );
165 * Decodes a 32 char long hexadecimal representation of a MD4 hash.
167 * @param hash The hash representation to be converted. Length must be 32.
168 * @return Return value specifies if the hash was succesfully decoded.
170 * This function converts a hexadecimal representation of a MD4
171 * hash and stores it in the m_hash data-member.
174 bool Decode(const std::string& hash) {
175 if (hash.length() != MD4HASH_LENGTH * 2) {
176 return false;
179 for ( size_t i = 0; i < MD4HASH_LENGTH * 2; i++ ) {
180 unsigned char word = toupper(hash[i]);
182 if ((word >= '0') && (word <= '9')) {
183 word -= '0';
184 } else if ((word >= 'A') && (word <= 'F')) {
185 word -= 'A' - 10;
186 } else {
187 // Invalid chars
188 return false;
191 if (i % 2 == 0) {
192 m_hash[i/2] = word << 4;
193 } else {
194 m_hash[i/2] += word;
198 return true;
201 #ifdef USE_WX_EXTENSIONS
202 bool Decode(const wxString& hash) {
203 return Decode(std::string(unicode2char(hash)));
205 #endif
207 /**
208 * Creates a 32 char long hexadecimal representation of a MD4 hash.
210 * @return Hexadecimal representation of the m_hash data-member.
212 * This function creates a hexadecimal representation of the MD4
213 * hash stored in the m_hash data-member and returns it.
215 std::string EncodeSTL() const {
216 std::string Base16Buff;
218 for ( size_t i = 0; i < MD4HASH_LENGTH*2; i++ ) {
219 size_t x = ( i % 2 == 0 ) ? ( m_hash[i/2] >> 4 ) : ( m_hash[i/2] & 0xf );
221 if ( x < 10 ) {
222 Base16Buff += (char)( x + '0' );
223 } else {
224 Base16Buff += (char)( x + ( 'A' - 10 ));
228 return Base16Buff;
231 #ifdef USE_WX_EXTENSIONS
232 wxString Encode() const {
233 return char2unicode(EncodeSTL().c_str());
235 #endif
238 * Explicitly set the hash-array to the contents of a unsigned char array.
240 * @param hash The array to be assigned.
242 * The hash must either be a NULL pointer or be of length 16.
244 void SetHash(const unsigned char hash[]) {
245 if ( hash ) {
246 RawPokeUInt64( m_hash, RawPeekUInt64( hash ) );
247 RawPokeUInt64( m_hash + 8, RawPeekUInt64( hash + 8 ) );
248 } else {
249 Clear();
254 * Explicit access to the hash-array.
256 * @return Pointer to the hash array.
258 unsigned char* GetHash() {
259 return m_hash;
261 const unsigned char* GetHash() const {
262 return m_hash;
266 * Explic access to values in the hash-array.
268 * @param i An index less than the length of an MD4 hash.
269 * @return The value (or its reference) at the given index.
271 unsigned char operator[](size_t i) const {
272 MULE_VALIDATE_PARAMS(i < MD4HASH_LENGTH, wxT("Invalid index in CMD4Hash::operator[]"));
273 return m_hash[i];
276 unsigned char& operator[](size_t i) {
277 MULE_VALIDATE_PARAMS(i < MD4HASH_LENGTH, wxT("Invalid index in CMD4Hash::operator[]"));
278 return m_hash[i];
281 private:
282 //! The raw MD4-hash.
284 //! The raw representation of the MD4-hash. In most cases, you should
285 //! try to avoid direct access and instead use the member functions.
286 unsigned char m_hash[MD4HASH_LENGTH];
290 #endif
291 // File_checked_for_headers