Developers.Hash.RoundTrip20

From Shareaza Wiki
Jump to navigation Jump to search

Hash to text and back again

Same thing, now in the 2.0 code. Here, it's easy to see what methods each class offers by looking at their .h files. I want to test:

MD4.h (There are no text methods here)

MD5.h HashToString(const MD5* pHash, BOOL bURN = FALSE); HashFromString(LPCTSTR pszHash, MD5* pMD5); HashFromURN(LPCTSTR pszHash, MD5* pMD5);

SHA.h GetHashString(BOOL bURN = FALSE); HashToString(const SHA1* pHash, BOOL bURN = FALSE); HashToHexString(const SHA1* pHash, BOOL bURN = FALSE); HashFromString(LPCTSTR pszHash, SHA1* pHash); HashFromURN(LPCTSTR pszHash, SHA1* pHash);

TigerTree.h RootToString();

ED2K.h HashToString(const MD4* pHash, BOOL bURN = FALSE); HashFromString(LPCTSTR pszHash, MD4* pHash); HashFromURN(LPCTSTR pszHash, MD4* pHash);

Here they all are in action:

MD4

<source lang="c"> // Takes a pointer to some memory and the number of bytes of data there // Computes MD4 hashes of the information and converts it to and from text void HashMD4(byte* p, DWORD bytes) {

// Hash the data CMD4 hash; // Make the object that will compute the hash hash.Add(p, bytes); // Give the object the data to hash hash.Finish(); // Tell the hash object that is all the data we are going to add

// Get the hash value MD4 value; // Make a local instance of a structure to hold the hash value DWORD size = sizeof(value); // The value is 16 bytes, 128 bits, 32 hex characters hash.GetHash(&value); // Get the hash value

// Convert it to text CString direct; direct = tobase16byte*)(&value), sizeof(value; // "866437cb7a794bce2b727acc0362ee27" for "hello" } </source>

MD4 doesn't have any methods that express a hash as text. The Shareaza code borrows the static method MD5::HashToString to do it because both MD4 and MD5 are 16 bytes.

MD5

<source lang="c"> // Takes a pointer to some memory and the number of bytes of data there // Computes MD5 hashes of the information and converts it to and from text void HashMD5(byte* p, DWORD bytes) {

// Hash the data CMD5 hash; // Make the object that will compute the hash hash.Add(p, bytes); // Give the object the data to hash hash.Finish(); // Tell the hash object that is all the data we are going to add

// Get the hash value MD5 value; // Make a local instance of a structure to hold the hash value DWORD size = sizeof(value); // The value is 16 bytes, 128 bits, 32 hex characters hash.GetHash(&value); // Get the hash value

// Convert it to text CString direct, tostring, tourn; direct = tobase16byte*)(&value), sizeof(value; // "5d41402abc4b2a76b9719d911017c592" for "hello" tostring = CMD5::HashToString(&value, false); // "5d41402abc4b2a76b9719d911017c592" tourn = CMD5::HashToString(&value, true); // "md5:5d41402abc4b2a76b9719d911017c592"

// Turn the text back into hash values MD5 value1, value2; CMD5::HashFromString(tostring, &value1); // Takes just base 16 characters CMD5::HashFromURN(tourn, &value2); // Takes "md5:" followed by base 16 characters

// Make sure that didn't change anything CString direct2, direct3; direct2 = CMD5::HashToString(&value1, false); direct3 = CMD5::HashToString(&value2, false); } </source>

MD5 is using base 32 lowercase, and has a header md5:

SHA1

<source lang="c"> // Takes a pointer to some memory and the number of bytes of data there // Computes SHA1 hashes of the information and converts it to and from text void HashSHA1(byte* p, DWORD bytes) {

// Hash the data CSHA hash; // Make the object that will compute the hash hash.Add(p, bytes); // Give the object the data to hash hash.Finish(); // Tell the hash object that is all the data we are going to add

// Get the hash value SHA1 value; // Make a local instance of a structure to hold the hash value DWORD size = sizeof(value); // The value is 20 bytes, 160 bits, 40 hex characters hash.GetHash(&value); // Get the hash value

// You can have the hash object tell us the base 32 text directly CString s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; s1 = hash.GetHashString(false); // "VL2MMHO4YXUKFWV63YHTWSBM3GXKSQ2N" for "hello" s2 = hash.GetHashString(true); // "urn:sha1:VL2MMHO4YXUKFWV63YHTWSBM3GXKSQ2N"

// Access the memory of the hash value directly and express it in base 16 and 32 text s3 = tobase16byte*)(&value), sizeof(value.MakeUpper(); // "AAF4C61DDCC5E8A2DABEDE0F3B482CD9AEA9434D" s4 = tobase32byte*)(&value), sizeof(value.MakeUpper(); // "VL2MMHO4YXUKFWV63YHTWSBM3GXKSQ2N"

// Use static methods to generate base 16 and base 32 text with and without the "urn:sha1:" header s5 = CSHA::HashToHexString(&value, false); // "AAF4C61DDCC5E8A2DABEDE0F3B482CD9AEA9434D" s6 = CSHA::HashToHexString(&value, true); // "urn:sha1:AAF4C61DDCC5E8A2DABEDE0F3B482CD9AEA9434D" s7 = CSHA::HashToString(&value, false); // "VL2MMHO4YXUKFWV63YHTWSBM3GXKSQ2N" s8 = CSHA::HashToString(&value, true); // "urn:sha1:VL2MMHO4YXUKFWV63YHTWSBM3GXKSQ2N"

// Use static methods to turn those strings back into hash values SHA1 value1, value2; CSHA::HashFromString(s7, &value1); // Takes just base 32 characters CSHA::HashFromURN(s8, &value2); // Takes "urn:sha1:" followed by base 32 characters

// Convert those hash values back into strings, make sure you get the same thing s9 = CSHA::HashToString(&value1, false); // "VL2MMHO4YXUKFWV63YHTWSBM3GXKSQ2N" s10 = CSHA::HashToString(&value2, false); // "VL2MMHO4YXUKFWV63YHTWSBM3GXKSQ2N" } </source>

For SHA1, the Shareaza 2.0 code offers both base 16 and base 32 as options. Uppercase base 32 seems to be the default, and the header is urn:sha1:

TigerTree

<source lang="c"> // Takes a pointer to some memory and the number of bytes of data there // Computes the TigerTree root hash of the information and converts it to and from text void HashTiger(byte* p, DWORD bytes) {

// Compute the TigerTree root hash for the file CTigerTree hash; // The object that will compute the hash hash.BeginFile(9, bytes); // Tell it the tiger height is 9, and the file size hash.AddToFile(p, bytes); // Give it the data to hash hash.FinishFile(); // That's all

// Get the TigerTree root hash value TIGEROOT value; // The variable that will store the hash value DWORD size = sizeof(value); // 24 bytes hash.GetRoot(&value); // Get the hash value from the object

// Convert it to text CString direct, root; direct = tobase32byte*)(&value), sizeof(value.MakeUpper(); // "HGHPJWCDKPF6B6BRUZCBR4YBFJKBSSKHE4MG53I" for "hello" root = hash.RootToString(); // "HGHPJWCDKPF6B6BRUZCBR4YBFJKBSSKHE4MG53I" } </source>

TigerTree is using uppercase base 32. The code doesn't have an option to stick on a URN header.

eDonkey2000

<source lang="c"> // Takes a pointer to some memory and the number of bytes of data there // Computes the eDonkey2000 root hash of the information and converts it to and from text void HashDonkey(byte* p, DWORD bytes) {

// Compute the root hash for the file using MD4 the way eDonkey2000 does CED2K hash; // The object that will compute the hash hash.BeginFile(bytes); // Tell it the file size hash.AddToFile(p, bytes); // Give it the data to hash hash.FinishFile(); // That's all

// Get the eDonkey2000 root hash value MD4 value; // The variable that will store the hash value DWORD size = sizeof(value); // 16 bytes hash.GetRoot(&value); // Get the hash value from the object

// Convert it to text CString direct, tostring, tourn; direct = tobase16byte*)(&value), sizeof(value; // "866437cb7a794bce2b727acc0362ee27" for "hello" tostring = CED2K::HashToString(&value, false); // "866437cb7a794bce2b727acc0362ee27" tourn = CED2K::HashToString(&value, true); // "urn:ed2khash:866437cb7a794bce2b727acc0362ee27"

// Turn it back into hash values MD4 value2, value3; CED2K::HashFromString(tostring, &value2); CED2K::HashFromURN(tourn, &value3);

// Make sure that didn't change anything CString direct2, direct3; direct2 = tobase16byte*)(&value2), sizeof(value2; direct3 = tobase16byte*)(&value3), sizeof(value3; } </source>

eDonkey2000 is using lowercase base 16. The header is urn:ed2khash: