Developers.Hash.Value

From Shareaza Wiki
Jump to navigation Jump to search

Hash value types

A MD4 hash takes up 16 bytes, which is 128 bits, and can be expressed as 32 hexadecimal characters. A MD5 hash takes up 16 bytes, which is 128 bits, and can be expressed as 32 hexadecimal characters. A SHA1 hash takes up 20 bytes, which is 160 bits, and can be expressed as 40 hexadecimal characters. A TigerTree root hash takes up 24 bytes, which is 192 bits, and can be expressed as 48 hexadecimal characters.

Hash value types in the Shareaza 2.0 code

Here's some code that shows the size of these hash values in Shareaza 2.0:

<source lang="c"> // Show the size of each hash value DWORD size; size = sizeof(MD4); // 16 bytes, 128 bits, 32 hex characters size = sizeof(MD5); // 16 bytes, 128 bits, 32 hex characters size = sizeof(SHA1); // 20 bytes, 160 bits, 40 hex characters size = sizeof(TIGEROOT); // 24 bytes, 192 bits, 48 hex characters </source>

In the Shareaza 2.0 code, the hash value types are defined in StfAfx.h:

<source lang="c"> typedef union { BYTE n[20]; BYTE b[20]; } SHA1;

typedef union { BYTE n[24]; BYTE b[24]; QWORD w[3]; } TIGEROOT;

typedef union { BYTE n[16]; BYTE b[16]; DWORD w[4]; } MD4, MD5; </source>

The SHA1 type is an array of 20 bytes, TIGEROOT takes up 24 bytes, and both MD4 and MD5 are 16 bytes.

The code uses union to look at the memory of the structure several different ways. Within a SHA1, you can access the array of 20 bytes using the member named n or the member named b. You can get to the 16 bytes of a MD5 individually with n, or as an array of 4 DWORDs with w.

Hash value types in camper's code

In camper's code, the hash value types are not traditional data types. Calling sizeof on them doesn't work. Instead, the sizes are defined in members you can read.

<source lang="c"> // Read the size constants for the value of a SHA1 hash int i; i = Hashes::Sha1Hash::byteCount; // A SHA1 hash value has a size of 20 bytes i = Hashes::Sha1Hash::wordCount; // This is 5 word types i = sizeof(Hashes::Sha1Hash::WordType); // Where the word type is 4 bytes, like an int or DWORD

// Get the size of the SHA1 hash two different ways i = Hashes::Sha1Hash::byteCount; // Read its size directly, 20 bytes i = Hashes::Sha1Hash::wordCount * sizeof(Hashes::Sha1Hash::WordType); // Multiply the word count to get 20 </source>

The size in bytes is byteCount. A SHA1 hash is 20 bytes. This is 5 4-byte DWORDs, as expressed with a wordCount of 5 and WordType DWORD. You can use sizeof on WordType, which will be DWORD, and result in the number 4.

Here are all the size constants that camper's code defines

<source lang="c"> // Read the byte counts size = Hashes::Sha1Hash::byteCount; // 20 size = Hashes::Sha1ManagedHash::byteCount; // 20 size = Hashes::TigerHash::byteCount; // 24 size = Hashes::TigerManagedHash::byteCount; // 24 size = Hashes::Ed2kHash::byteCount; // 16 size = Hashes::Ed2kManagedHash::byteCount; // 16 size = Hashes::Md5Hash::byteCount; // 16 size = Hashes::Md5ManagedHash::byteCount; // 16 size = Hashes::BtHash::byteCount; // 20 size = Hashes::BtPureHash::byteCount; // 20 size = Hashes::BtManagedHash::byteCount; // 20 size = Hashes::Guid::byteCount; // 16 size = Hashes::BtGuid::byteCount; // 20, larger than a normal guid </source>

There are 2 types for each hash, normal and managed. Just as with Shareaza 2.0, MD4 and MD5 are 16 bytes, SHA1 is 20, and TigerTree is 24.

Three new types are defined for BitTorrent: BtHash, BtPureHash, and BtManagedHash. They are all 20 bytes, just like SHA1.

There are also two types for GUIDs: Guid, which is 16 bytes, and BtGuid which is 20, 4 bytes larger than a normal GUID.

  • Is this a complete list of the types the code defines?
  • What is a manged hash?
  • Why is MD4 missing? Is this Ed2k?
  • Are the 20 byte BitTorrent hashes really just for SHA1?
  • Why is BtGuid 4 bytes larger than a normal 16 byte GUID?

Here are the results of calling sizeof on each WordType:

<source lang="c"> // Find out how big the word type is size = sizeof(Hashes::Sha1Hash::WordType); // 4 size = sizeof(Hashes::Sha1ManagedHash::WordType); // 4 size = sizeof(Hashes::TigerHash::WordType); // 8, a QWORD size = sizeof(Hashes::TigerManagedHash::WordType); // 8, a QWORD size = sizeof(Hashes::Ed2kHash::WordType); // 4 size = sizeof(Hashes::Ed2kManagedHash::WordType); // 4 size = sizeof(Hashes::Md5Hash::WordType); // 4 size = sizeof(Hashes::Md5ManagedHash::WordType); // 4 size = sizeof(Hashes::BtHash::WordType); // 4 size = sizeof(Hashes::BtPureHash::WordType); // 4 size = sizeof(Hashes::BtManagedHash::WordType); // 4 size = sizeof(Hashes::Guid::WordType); // 4 size = sizeof(Hashes::BtGuid::WordType); // 4 </source>

Most word types are 4-byte DWORDs. TigerHash and TigerManagedHash use 8-byte QWORDs instead. Here are the word counts:

<source lang="c"> // Read the word counts size = Hashes::Sha1Hash::wordCount; // 5 size = Hashes::Sha1ManagedHash::wordCount; // 5 size = Hashes::TigerHash::wordCount; // 3, due to the larger word size = Hashes::TigerManagedHash::wordCount; // 3, due to the larger word size = Hashes::Ed2kHash::wordCount; // 4 size = Hashes::Ed2kManagedHash::wordCount; // 4 size = Hashes::Md5Hash::wordCount; // 4 size = Hashes::Md5ManagedHash::wordCount; // 4 size = Hashes::BtHash::wordCount; // 5 size = Hashes::BtPureHash::wordCount; // 5 size = Hashes::BtManagedHash::wordCount; // 5 size = Hashes::Guid::wordCount; // 4 size = Hashes::BtGuid::wordCount; // 5, larger than a normal guid </source>

The tiger counts are lower because of the larger word. Guid is 4 DWORDs, totaling 16 bytes, while BtGuid has an extra one to get to its size of 20 bytes.