我需要基于 FirstName/LastName 组合构建一个哈希。在数据库中,每个最大值都是 100 个字符,并且哈希值最多需要 20 个字符。
有没有办法在此基础上可靠地产生独特的价值?假设 FirstName/LastName 组合是唯一的。
哈希永远不能绝对保证是唯一的,它们不应该用作唯一标识符。
实际上,良好的加密哈希值几乎与它们各自的消息一样独特。您所描述的内容看起来非常像 SHA-1,如果您希望相同的 FirstName/LastName 映射到相同的“唯一”20 个字符。完整的 SHA-1 比 GUID 大(说明了什么),并且作为加密,分布相当均匀,不太可能发生冲突(参见 SHA-1 的冲突攻击——即使是故意的也很难做到)。
听起来您希望表中的每条记录都有一个唯一标识符,而且这个标识符不容易猜到。有多种方法可以实现这一目标,包括:
1.为带有unique
约束的标识符添加一列,并在插入列时生成随机标识符。如果由于标识符已经存在而导致插入失败,请生成新标识符并重试。
2.在表中添加一auto GUID
列,让数据库生成唯一标识符。
3.向表中添加一auto-increment int
列,让数据库生成唯一标识符并对其进行混淆处理。例如,您可以通过将整数填充为 16 并使用 128 位分组密码对其进行加密来做到这一点。例子:
private static readonly AesManaged cipher = new AesManaged()
{
BlockSize = 128,
Key = Encoding.UTF8.GetBytes("secret__secret__"),
Mode = CipherMode.ECB,
Padding = PaddingMode.None
};
static string Obfuscate(int id)
{
using (var transform = cipher.CreateEncryptor())
{
return Convert.ToBase64String(
transform.TransformFinalBlock(
Encoding.UTF8.GetBytes(
id.ToString("0000000000000000")), 0, 16));
}
}
static int Deobfuscate(string s)
{
using (var transform = cipher.CreateDecryptor())
{
return int.Parse(
Encoding.UTF8.GetString(
transform.TransformFinalBlock(
Convert.FromBase64String(s), 0, 16)));
}
}
请注意,这些方法都无法猜测标识符,只是比将整数加 1 更困难。您仍然需要检查用户是否有权查看与标识符关联的信息。