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

C# 如何为地址结构生成唯一标识符?,c#,algorithm,hash,perfect-hash,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; } } 我正在寻找一种方

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

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; }
} 
我正在寻找一种方法来为这个结构创建一个唯一的标识符(我假设它也应该是一种
字符串
),这取决于所有结构属性(例如
地址行1
的更改也会导致结构标识符的更改)

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

我还假设不同地址的数量不应超过100万个

关于如何生成该标识符有什么想法吗

提前谢谢

这方面的史前史:

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

不幸的是,现在将地址数据移动到一个单独的表中是非常昂贵的,但我希望将来会这样做


我需要将一些附加属性与地址数据关联起来,并为此创建一个单独的表。这就是我需要唯一标识地址数据的原因。

将所有字段序列化为一个大的二进制值。例如,使用具有适当域分隔的串联


然后使用足够长的加密哈希对该值进行哈希。我更喜欢256位,但128位可能还可以。使用好的哈希,冲突非常罕见,使用像SHA-256这样的256位哈希,冲突几乎是不可能的。

下面是一个使用序列化、sha256哈希和base64编码(基于CodesInChaos答案)的完整示例:

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

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;
}

请给我们更多的背景。几乎可以肯定的是,有一种更好的方法来解决这个问题。在一般意义上,没有办法生成一个完美的哈希函数。首先,你需要拥有100万个唯一的地址,然后有一些算法和软件可以创建你的函数,将每个地址映射成一个唯一的数字,而不必存储它们。正如Jon所说,很可能有一种更好的方法来解决您的问题,而不是尝试制作一个完美的散列。我不喜欢为此使用
BinaryFormatter
。您需要某种函数来保证每次调用时都能得到相同的结果,无论您使用的是.net还是mono版本。我认为,
BinaryFormatter
不能保证这一点。我可能会在单个值上与串联一起使用。您还有一个错误:
stream.GetBuffer()
应该是
stream.ToArray()
。谢谢您的回答。这似乎是最简单的解决办法。在问这个问题之前,我已经有过类似的想法:)但我想等一下,也许有人会提供另一种解决方案。
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;
}