2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
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
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
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>
42 const size_t MD4HASH_LENGTH
= 16;
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!
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.
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
);
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
[]) {
97 * Returns true if all fields of both hashes are the same.
99 bool operator == (const CMD4Hash
& other_hash
) const {
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
] ) {
127 } else if ( other_hash
.m_hash
[i
] < m_hash
[i
] ) {
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 {
147 !RawPeekUInt64( m_hash
) &&
148 !RawPeekUInt64( m_hash
+ 8 )
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.
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) {
179 for ( size_t i
= 0; i
< MD4HASH_LENGTH
* 2; i
++ ) {
180 unsigned char word
= toupper(hash
[i
]);
182 if ((word
>= '0') && (word
<= '9')) {
184 } else if ((word
>= 'A') && (word
<= 'F')) {
192 m_hash
[i
/2] = word
<< 4;
201 #ifdef USE_WX_EXTENSIONS
202 bool Decode(const wxString
& hash
) {
203 return Decode(std::string(unicode2char(hash
)));
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 );
222 Base16Buff
+= (char)( x
+ '0' );
224 Base16Buff
+= (char)( x
+ ( 'A' - 10 ));
231 #ifdef USE_WX_EXTENSIONS
232 wxString
Encode() const {
233 return char2unicode(EncodeSTL().c_str());
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
[]) {
246 RawPokeUInt64( m_hash
, RawPeekUInt64( hash
) );
247 RawPokeUInt64( m_hash
+ 8, RawPeekUInt64( hash
+ 8 ) );
254 * Explicit access to the hash-array.
256 * @return Pointer to the hash array.
258 unsigned char* GetHash() {
261 const unsigned char* GetHash() const {
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[]"));
276 unsigned char& operator[](size_t i
) {
277 MULE_VALIDATE_PARAMS(i
< MD4HASH_LENGTH
, wxT("Invalid index in CMD4Hash::operator[]"));
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
];
291 // File_checked_for_headers