简体   繁体   中英

Create a simple hash value of database columns using c# .net

I would like to store a simple hash value of n number of columns eg address and name, and store the hash in another column. I want to use the hash value as a quick way of synchronising data between 2 sources, by simply comparing the hash value. What is the best way of doing something like this. I don't need crypto functionality just to create the hash.

eg

John Smith, 1 Long Lane Road, Village, Town, Postcode. Hash: AK67KS38

I would like the hash value to be simple enough to be readable (not have whole range of Uni-code set).

Edit Ok I would still like to do this in c# code and LINQ. The data is brought in externally through interrogating other sources. There is no other way to link this uniquely with my data as there is no 'key' as such from the external source to link to. So in this sense, a timestamp value would not be an option. I understand this method is not 'exact' but I can live with that. I might add the ability to review manually the possible hash matches and promote them further into the database if they are acceptable.

Jon - an alternative approach would be to add a timestamp column onto the table (or in the object). set this to UTC and be done with it. of course, you could argue about concurrency on edits etc., but you'd have a far more difficult job to determine the latest edit/diff if you were only comparing the hash column values.

however, if the hash column approach is a 'must', then you should be very careful of this across database installations on different cultures as the mechanism can vary. i'd carefully consider the merits of the timestamp vs the hash in this case.

[edit] Jon, based on your recent edit, i'd then suggest creating a custom GetHashCode() and Equals() on your object and using the comparer to do the grunt work for you. i did a quick google to figure what might be useful. a reasonable (2 minute google) starting point might be here:

http://www.eggheadcafe.com/community/aspnet/2/78458/hashcode.aspx

and here is a quick code example (based on your requirement of name and address being used for the hash [thank you resharper :-)]):

public class ContactDetails
{
    public string Name { get; set; }
    public string Address { get; set; }
    public string Village { get; set; }
    public string Town { get; set; }
    public string PostCode { get; set; }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != typeof (ContactDetails)) return false;
        return Equals((ContactDetails) obj);
    }

    public bool Equals(ContactDetails other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return Equals(other.Name, Name) && Equals(other.Address, Address);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((Name != null ? Name.GetHashCode() : 0)*397) 
                ^ (Address != null ? Address.GetHashCode() : 0);
        }
    }
}

typical usage:

bool isChanged = ContactFromServer1.Equals(ContactFromServer2);
//etc..

hope this helps

Assuming your columns are copied to a User instance (user):

DataContractSerializer serializer = new DataContractSerializer(typeof(User));
MemoryStream memoryStream = new MemoryStream();
XmlWriter writer = XmlDictionaryWriter.CreateBinaryWriter(memoryStream);
serializer.WriteObject(memoryStream, user);
byte[] serializedData = memoryStream.ToArray();

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

// Convert the hash to a base 64 string
string hashAsText = Convert.ToBase64String(hash);

Note that I've converted the hash to a base 64 string and that you could use MD5 too as the hash is calculated for checksum purposes

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM