SUMMARY
This step-by-step article describes how to obtain a
hash value
and how to compare two
hash values to check whether they are identical.
back to the topRequirements
The following list outlines the
recommended hardware, software, network infrastructure, and service packs that
you need:
- Microsoft Windows 2000, Windows XP Professional or Windows
Server 2003
- Microsoft Visual C++ .NET or Microsoft Visual C++ 2005
back to the topCompute a hash value
It is easy to generate and compare
hash values by using the
cryptographic resources that are contained in the
System.Security.Cryptography
namespace. Because all
hash functions take input of type Byte[], you might have to convert the source into a byte array before it is hashed. To
create a
hash for a string value, follow these steps:
- Start Microsoft Visual Studio .NET or Microsoft Visual Studio 2005.
- On the File menu, point to New, and then click Project.
- In Visual Studio .NET 2002, click Visual C++ Projects under Project Types, and then click Managed C++ Application under Templates.
In
Visual C++ .NET 2003, click Visual C++ Projects under Project Types, and then click Console Application (.NET) under Templates.
In
Visual C++ 2005, click Visual C++ under Project Types, and then click CLR Console Application under Templates. - Name the project Q815656. Visual Studio .NET or Visual Studio 2005 creates a public class with a _tmain function.
- Use the using directive on the System, System.Security, System.Security.Cryptographic, and System.Text namespaces so that you do not have to qualify declarations
from these namespaces later in your code. To do this, add the following lines at
the top of Q815656.cpp.
using namespace System;
using namespace System::Security::Cryptography;
using namespace System::Text;
- At the beginning of the _main function, declare a string variable to hold your source data, and
two byte arrays (of undefined size) to hold the source bytes and the resulting
hash value.
String* sSourceData;
Byte tmpSource[];
Byte tmpHash[];
- Use the GetBytes method to convert your source string into an array of bytes
(required as input to the hashing function). The GetBytes method is a member of the System.Text.ASCIIEncoding class.
ASCIIEncoding* ascii = new ASCIIEncoding();
sSourceData = "MySourceData";
//Create a byte array from source data.
tmpSource = ascii->GetBytes(sSourceData);
- Compute the MD5 hash for your source data by calling the ComputeHash method on an instance of the MD5CryptoServiceProvider class. Note To compute another hash value,
create another instance of the class.
//Compute hash based on source data.
tmpHash = (new MD5CryptoServiceProvider())->ComputeHash(tmpSource);
- The tmpHash byte array now holds the
computed hash value (128-bit value=16 bytes) for your source data. It is frequently
useful to display or store a value like this as a hexadecimal string. Use the following code to do this.
Console::WriteLine(ByteArrayToString(tmpHash));
- Add the following ByteArrayToString function definition below the _tmain function.
String* ByteArrayToString(Byte arrInput[])
{
int i;
StringBuilder* sOutput = new StringBuilder(arrInput->Length);
for (i=0;i < arrInput->Length -1; i++)
{
sOutput->Append(arrInput[i].ToString("X2"));
}
return sOutput->ToString();
}
Note You must add the following function declaration
before the _tmain function.String* ByteArrayToString(Byte arrInput[]);
Otherwise, you receive the C3861 and C2365 errors in Visual C++ .NET 2003, or you receive the C2365 and C2365 errors in Visual C++ .NET 2002 - Press CTRL+F5 to save and run your code. You
see output that is similar to the following:8FD2486D263C1EE4FCF7FA70742F23
back to the topCompare two hash values
When you create a
hash from source data, you can see if data has changed over time, or you can compare two values
without ever working with the actual values. In either case, you must
compare two computed hashes. You can compare the computed hashes easily if they are both stored as
hexadecimal strings (as in the last step of the earlier section). However, both might be in the form of byte arrays. The following
code continues from the code that was created in the previous section. This code demonstrates how
to compare two byte arrays.
- Below the hexadecimal string that is created, create a
new hash value that is based on new source data.
sSourceData = "NotMySourceData";
//Create a byte array from source data.
tmpSource = ascii->GetBytes(sSourceData);
Byte tmpNewHash[];
tmpNewHash = (new MD5CryptoServiceProvider())->ComputeHash(tmpSource);
- The most straightforward way to compare two byte arrays is
to loop through the arrays and compare each element to its
counterpart from the second value. If any elements are different, or if the two
arrays are not the same size, the two values are not equal.
bool bEqual = false;
if (tmpNewHash->Length == tmpHash->Length)
{
int i=0;
while ((i < tmpNewHash->Length) && (tmpNewHash[i] == tmpHash[i]))
{
i += 1;
}
if (i == tmpNewHash->Length)
{
bEqual = true;
}
}
if (bEqual)
Console::WriteLine("The two hash values are the same");
else
Console::WriteLine("The two hash values are not the same");
Console::ReadLine();
- Press CTRL+F5 to save and run your code. You see output that is similar to the following:
8FD2486D263C1EE4FCF7FA70742F23
F7711A634146F20AB86D1E5A8F870C
The two hash values are not the same
back to the topComplete code listing
#include "stdafx.h"
#include <tchar.h>
#using <mscorlib.dll>
using namespace System;
using namespace System::Security::Cryptography;
using namespace System::Text;
String* ByteArrayToString(Byte arrInput[]);
int _tmain(void)
{
// TODO: Replace the sample code below with your own.
String* sSourceData;
Byte tmpSource[];
Byte tmpHash[];
ASCIIEncoding* ascii = new ASCIIEncoding();
sSourceData = "MySourceData";
//Create a byte array from source data.
tmpSource = ascii->GetBytes(sSourceData);
tmpHash = (new MD5CryptoServiceProvider())->ComputeHash(tmpSource);
Console::WriteLine(ByteArrayToString(tmpHash));
sSourceData = "NotMySourceData";
tmpSource =ascii->GetBytes(sSourceData);
Byte tmpNewHash[];
tmpNewHash = (new MD5CryptoServiceProvider())->ComputeHash(tmpSource);
Console::WriteLine(ByteArrayToString(tmpNewHash));
bool bEqual = false;
if (tmpNewHash->Length == tmpHash->Length)
{
int i=0;
while ((i < tmpNewHash->Length) && (tmpNewHash[i] == tmpHash[i]))
{
i += 1;
}
if (i == tmpNewHash->Length)
{
bEqual = true;
}
}
if (bEqual)
Console::WriteLine("The two hash values are the same");
else
Console::WriteLine("The two hash values are not the same");
Console::ReadLine();
return 0;
};
String* ByteArrayToString(Byte arrInput[])
{
int i;
StringBuilder* sOutput = new StringBuilder(arrInput->Length);
for (i=0;i < arrInput->Length -1; i++)
{
sOutput->Append(arrInput[i].ToString("X2"));
}
return sOutput->ToString();
};
Note You must add the common language runtime support compiler option (/clr:oldSyntax) in
Visual C++ 2005 to successfully compile the previous code sample.
To add the common language runtime support compiler option in Visual C++ 2005, follow these steps:
- Click Project, and then click <ProjectName> Properties.
Note <ProjectName> is a placeholder for the
name of the project. - Expand Configuration Properties, and then click
General.
- Click to select Common Language Runtime Support, Old Syntax (/clr:oldSyntax) in the
Common Language Runtime support project setting in the right pane, click Apply, and then
click OK.
For more information about the common language runtime support compiler option, visit the following Microsoft Web site:
These steps apply to the whole article.
back to the topREFERENCES
For more information about how to use the cryptographic
features of the Microsoft .NET Framework, and about cryptography,
visit the following Massachusetts Institute of Technology
Web site:
For more information about
hashing functions, visit the following RSA Security Web site:
Microsoft provides third-party contact information to help you find technical support. This contact information may change without notice. Microsoft does not guarantee the accuracy of this third-party contact information.
back to the top