Review Kademlia assertions
[amule.git] / src / MD4Hash.h
blob4c91449991255293cefd7796bcd7c532f590ed1e
1 //
2 // This file is part of the aMule Project.
3 //
4 // Copyright (c) 2003-2011 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.
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 <common/MuleDebug.h> // Needed for MULE_VALIDATE_PARAMS
33 #ifdef USE_WX_EXTENSIONS
34 #include <common/StringFunctions.h>
35 #endif
37 #include <string>
40 const size_t MD4HASH_LENGTH = 16;
43 /**
44 * Container-class for the MD4 hashes used in aMule.
46 * This is a safe representation of the MD4 hashes used in aMule. By transparently
47 * wrapping the char array used to store the hash, we get the advantages of
48 * assigment, equality and non-equality operators, plus other nifty features.
50 * Please remember that the hashes are arrays with length 16 WITHOUT a zero-terminator!
52 class CMD4Hash
54 public:
55 /**
56 * Default constructor.
58 * The default constructor creates an empty hash of length 16.
59 * Each field of the char array has an initial value of zero.
61 CMD4Hash() {
62 Clear();
65 ~CMD4Hash() {
68 /**
69 * Cast a unsigned char array to a CMD4Hash.
71 * @param hash The array to be cast.
73 * Please note that the array must either be a NULL pointer or be at least
74 * 16 chars long, not including any possible zero-terminator!
76 explicit CMD4Hash(const unsigned char hash[]) {
77 SetHash(hash);
80 /**
81 * Equality operator.
83 * Returns true if all fields of both hashes are the same.
85 bool operator == (const CMD4Hash& other_hash) const {
86 return (
87 ( RawPeekUInt64( m_hash ) == RawPeekUInt64( other_hash.m_hash ) ) &&
88 ( RawPeekUInt64( m_hash + 8 ) == RawPeekUInt64( other_hash.m_hash + 8 ) )
92 /**
93 * Non-equality operator
95 * Returns true if there is any difference between the two hashes.
97 bool operator != (const CMD4Hash& other_hash) const {
98 return !(*this == other_hash);
102 * Less than operator.
104 * @return True if the hash is less than other_hash, false otherwise.
106 * The purpose of this function is to enable the usage of CMD4Hashes in
107 * sorted STL containers like std::map.
109 bool operator < (const CMD4Hash& other_hash) const {
110 for ( size_t i = 0; i < MD4HASH_LENGTH; ++i ) {
111 if ( m_hash[i] < other_hash.m_hash[i] ) {
112 return true;
113 } else if ( other_hash.m_hash[i] < m_hash[i] ) {
114 return false;
118 return false;
123 * Returns true if the hash is empty.
125 * @return True if all fields are zero, false otherwise.
127 * This functions checks the contents of the hash and returns true
128 * only if each field of the array contains the value zero.
129 * To achive an empty hash, the function Clear() can be used.
131 bool IsEmpty() const {
132 return (
133 !RawPeekUInt64( m_hash ) &&
134 !RawPeekUInt64( m_hash + 8 )
139 * Resets the contents of the hash.
141 * This functions sets the value of each field of the hash to zero.
142 * IsEmpty() will return true after a call to this function.
144 void Clear() {
145 RawPokeUInt64( m_hash, 0 );
146 RawPokeUInt64( m_hash + 8, 0 );
151 * Decodes a 32 char long hexadecimal representation of a MD4 hash.
153 * @param hash The hash representation to be converted. Length must be 32.
154 * @return Return value specifies if the hash was succesfully decoded.
156 * This function converts a hexadecimal representation of a MD4
157 * hash and stores it in the m_hash data-member.
160 bool Decode(const std::string& hash) {
161 if (hash.length() != MD4HASH_LENGTH * 2) {
162 return false;
165 for ( size_t i = 0; i < MD4HASH_LENGTH * 2; i++ ) {
166 unsigned char word = toupper(hash[i]);
168 if ((word >= '0') && (word <= '9')) {
169 word -= '0';
170 } else if ((word >= 'A') && (word <= 'F')) {
171 word -= 'A' - 10;
172 } else {
173 // Invalid chars
174 return false;
177 if (i % 2 == 0) {
178 m_hash[i/2] = word << 4;
179 } else {
180 m_hash[i/2] += word;
184 return true;
187 #ifdef USE_WX_EXTENSIONS
188 bool Decode(const wxString& hash) {
189 return Decode(std::string(unicode2char(hash)));
191 #endif
194 * Creates a 32 char long hexadecimal representation of a MD4 hash.
196 * @return Hexadecimal representation of the m_hash data-member.
198 * This function creates a hexadecimal representation of the MD4
199 * hash stored in the m_hash data-member and returns it.
201 std::string EncodeSTL() const {
202 std::string Base16Buff;
204 for ( size_t i = 0; i < MD4HASH_LENGTH*2; i++ ) {
205 size_t x = ( i % 2 == 0 ) ? ( m_hash[i/2] >> 4 ) : ( m_hash[i/2] & 0xf );
207 if ( x < 10 ) {
208 Base16Buff += (char)( x + '0' );
209 } else {
210 Base16Buff += (char)( x + ( 'A' - 10 ));
214 return Base16Buff;
217 #ifdef USE_WX_EXTENSIONS
218 wxString Encode() const {
219 return char2unicode(EncodeSTL().c_str());
221 #endif
224 * Explicitly set the hash-array to the contents of a unsigned char array.
226 * @param hash The array to be assigned.
228 * The hash must either be a NULL pointer or be of length 16.
230 void SetHash(const unsigned char hash[]) {
231 if ( hash ) {
232 RawPokeUInt64( m_hash, RawPeekUInt64( hash ) );
233 RawPokeUInt64( m_hash + 8, RawPeekUInt64( hash + 8 ) );
234 } else {
235 Clear();
240 * Explicit access to the hash-array.
242 * @return Pointer to the hash array.
244 unsigned char* GetHash() {
245 return m_hash;
247 const unsigned char* GetHash() const {
248 return m_hash;
252 * Explic access to values in the hash-array.
254 * @param i An index less than the length of an MD4 hash.
255 * @return The value (or its reference) at the given index.
257 unsigned char operator[](size_t i) const {
258 MULE_VALIDATE_PARAMS(i < MD4HASH_LENGTH, wxT("Invalid index in CMD4Hash::operator[]"));
259 return m_hash[i];
262 unsigned char& operator[](size_t i) {
263 MULE_VALIDATE_PARAMS(i < MD4HASH_LENGTH, wxT("Invalid index in CMD4Hash::operator[]"));
264 return m_hash[i];
267 private:
268 //! The raw MD4-hash.
270 //! The raw representation of the MD4-hash. In most cases, you should
271 //! try to avoid direct access and instead use the member functions.
272 unsigned char m_hash[MD4HASH_LENGTH];
276 #endif
277 // File_checked_for_headers