Skip to main content

Generate a unique hash string for an object. This is very useful if storing cached objects, and wanting to compare the hash of the cached object to a result of a service.

// ----------------------------------------------------------------------------
// Generating a unique hash string for an object
//
// This is just a quick tip on how to generate a unique hash string for an
// object. This is very useful when storing cached objects and want to compare a
// hash string of your cached objects and the results from a service. I did this
// by having two methods, one method will return the results and then other
// method will return the hash string. It is using the
// System.Security.Cryptography and System.Runtime.Serialization namespaces.
//
// https://talkdotnet.wordpress.com/2014/04/03/generating-a-unique-hash-string-for-an-object/
// ----------------------------------------------------------------------------

using System.Xml;
using System.Security.Cryptography;
using System.Runtime.Serialization;

public class Hashing
{
    public static string GenerateHashKey<T>(T oObject)
    {
        if (oObject == null)
        {
            return string.Empty;
        }

        DataContractSerializer serializer = new DataContractSerializer(typeof(T));
        using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
        {
            XmlWriter writer = XmlDictionaryWriter.CreateBinaryWriter(memoryStream);
            serializer.WriteObject(memoryStream, oObject);
            byte[] serializedData = memoryStream.ToArray();

            // Calculate the serialized data's hash value
            SHA1CryptoServiceProvider SHA = new SHA1CryptoServiceProvider();
            byte[] hash = SHA.ComputeHash(serializedData);

            // Convert the hash to a base 64 string
            return Convert.ToBase64String(hash);
        }
    }
}

// Usage:
// -----------------------------------------------------------------------

// The class structure of the object we going to be caching
//
// Create a class of User that is marked with the SerializableAttribute, this is
// the class that will be cached.

[Serializable]
public class User
{
    public string Username { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public DateTime DateOfBirth { get; set; }
}

// Implementation to get Users
//
// Create the below two methods (This in essence could be a WCF Service)

public class UserManagement
{
    public List<User> GetUsers()
    {
        List<User> users = new List<User>();
        users.Add(new User
        {
            Username = "TalkDotNet",
            Name = "Talk",
            Surname = "DotNet",
            DateOfBirth = new DateTime(1983, 9, 3)
        });
        users.Add(new User
        {
            Username = "JohnS",
            Name = "John",
            Surname = "Smith",
            DateOfBirth = new DateTime(1985, 8, 9)
        });
        return users;
    }

    public string GetUsersHash()
    {
        return Hashing.GenerateHashKey<List<User>>(GetUsers());
    }
}