2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2011 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 <common/MuleDebug.h> // Needed for MULE_VALIDATE_PARAMS
33 #ifdef USE_WX_EXTENSIONS
34 #include <common/StringFunctions.h>
40 const size_t MD4HASH_LENGTH
= 16;
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!
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.
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
[]) {
83 * Returns true if all fields of both hashes are the same.
85 bool operator == (const CMD4Hash
& other_hash
) const {
87 ( RawPeekUInt64( m_hash
) == RawPeekUInt64( other_hash
.m_hash
) ) &&
88 ( RawPeekUInt64( m_hash
+ 8 ) == RawPeekUInt64( other_hash
.m_hash
+ 8 ) )
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
] ) {
113 } else if ( other_hash
.m_hash
[i
] < m_hash
[i
] ) {
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 {
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.
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) {
165 for ( size_t i
= 0; i
< MD4HASH_LENGTH
* 2; i
++ ) {
166 unsigned char word
= toupper(hash
[i
]);
168 if ((word
>= '0') && (word
<= '9')) {
170 } else if ((word
>= 'A') && (word
<= 'F')) {
178 m_hash
[i
/2] = word
<< 4;
187 #ifdef USE_WX_EXTENSIONS
188 bool Decode(const wxString
& hash
) {
189 return Decode(std::string(unicode2char(hash
)));
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 );
208 Base16Buff
+= (char)( x
+ '0' );
210 Base16Buff
+= (char)( x
+ ( 'A' - 10 ));
217 #ifdef USE_WX_EXTENSIONS
218 wxString
Encode() const {
219 return char2unicode(EncodeSTL().c_str());
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
[]) {
232 RawPokeUInt64( m_hash
, RawPeekUInt64( hash
) );
233 RawPokeUInt64( m_hash
+ 8, RawPeekUInt64( hash
+ 8 ) );
240 * Explicit access to the hash-array.
242 * @return Pointer to the hash array.
244 unsigned char* GetHash() {
247 const unsigned char* GetHash() const {
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[]"));
262 unsigned char& operator[](size_t i
) {
263 MULE_VALIDATE_PARAMS(i
< MD4HASH_LENGTH
, wxT("Invalid index in CMD4Hash::operator[]"));
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
];
277 // File_checked_for_headers