我有一个描述地址的结构,它看起来像:
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。
有关如何生成此标识符的任何想法?
提前致谢。
史前史:
数据库中有几个不同的表,它们包含一些信息+地址数据。数据以与上述类似的格式存储。
不幸的是,现在将地址数据移到一个单独的表中是非常昂贵的,但我希望将来能够完成。
我需要将一些其他属性与地址数据相关联,然后为此创建一个单独的表。这就是我需要唯一识别地址数据的原因。
答案 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;
}