如何为地址结构生成唯一标识符?

时间:2013-04-07 11:51:39

标签: c# algorithm hash perfect-hash

我有一个描述地址的结构,它看起来像:

class Address
{
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string City { get; set; }
    public string Zip { get; set; }
    public string Country { get; set; }
} 

我正在寻找一种为此结构创建唯一标识符的方法(我假设它也应该是string的类型),这取决于所有结构属性(例如,AddressLine1的更改也会导致更改结构标识符。)

我知道,我可以将所有属性连接在一起,但这会给出太长的标识符。我正在寻找比这短得多的东西。

我还假设不同地址的数量不应超过100M。

有关如何生成此标识符的任何想法?

提前致谢。

史前史:

数据库中有几个不同的表,它们包含一些信息+地址数据。数据以与上述类似的格式存储。

不幸的是,现在将地址数据移到一个单独的表中是非常昂贵的,但我希望将来能够完成。

我需要将一些其他属性与地址数据相关联,然后为此创建一个单独的表。这就是我需要唯一识别地址数据的原因。

2 个答案:

答案 0 :(得分:3)

将所有字段序列化为较大的二进制值。例如,使用串联和正确的域分离。

然后使用足够长度的加密哈希散列该值。我更喜欢256位,但128可能没问题。良好的哈希冲突非常罕见,像SHA-256这样的256位哈希几乎是不可能的。

答案 1 :(得分:0)

这是一个使用序列化,sha256散列和base64编码的完整示例(基于CodesInChaos答案):

using System;
using System.IO;
using System.Security.Cryptography;
using System.Runtime.Serialization.Formatters.Binary;

namespace Uniq
{
    [Serializable]
    class Address
    {
        public string AddressLine1 { get; set; }
        public string AddressLine2 { get; set; }
        public string City { get; set; }
        public string Zip { get; set; }
        public string Country { get; set; }
    } 
    class MainClass
    {
        public static void Main (string[] args)
        {
            Address address1 = new Address(){AddressLine1 = "a1"};
            Address address2 = new Address(){AddressLine1 = "a1"};
            Address address3 = new Address(){AddressLine1 = "a2"};
            string unique1 = GetUniqueIdentifier(address1);
            string unique2 = GetUniqueIdentifier(address2);
            string unique3 = GetUniqueIdentifier(address3);
            Console.WriteLine(unique1);
            Console.WriteLine(unique2);
            Console.WriteLine(unique3);
        }
        public static string GetUniqueIdentifier(object obj){
            if (obj == null) return "0";
            SHA256 mySHA256 = SHA256Managed.Create ();
            BinaryFormatter formatter = new BinaryFormatter ();
            MemoryStream stream = new MemoryStream();
            formatter.Serialize(stream, obj);
            byte[] hash = mySHA256.ComputeHash(stream.GetArray());
            string uniqId = Convert.ToBase64String(hash);
            return uniqId;
        }
    }
}

编辑:这是一个不使用BinaryFormatter的版本。您可以将null表示和字段分隔符替换为适合您需要的任何内容。

public static string GetUniqueIdentifier(object obj){
    if (obj == null) return "0";
    SHA256 mySHA256 = SHA256Managed.Create ();
    StringBuilder stringRep = new StringBuilder();
    obj.GetType().GetProperties()
                .ToList().ForEach(p=>stringRep.Append(
            p.GetValue(obj, null) ?? '¨'
            ).Append('^'));
    Console.WriteLine(stringRep);
    Console.WriteLine(stringRep.Length);
    byte[] hash = mySHA256.ComputeHash(Encoding.Unicode.GetBytes(stringRep.ToString()));
    string uniqId = Convert.ToBase64String(hash);
    return uniqId;
}