无需订购即可对 UUID 进行哈希计算

问题描述 投票:0回答:3

我有两个 UUID。我想完美地对它们进行哈希处理以生成单个唯一值,但有一个限制,即 f(m,n)f(n,m) 必须生成相同的哈希值。

  • UUID 是 128 位值
  • 哈希函数应该没有冲突 - 所有可能的输入配对必须生成唯一的哈希值
  • f(m,n)f(n,m) 必须生成相同的哈希 - 也就是说,顺序并不重要
  • 我正在使用 Go,因此结果值必须适合 256 位 int
  • 哈希值不需要是可逆的

有人可以帮忙吗?

hash uuid hashcode hash-function
3个回答
4
投票

先将它们与较小的连接起来。


2
投票

为了构建 user2357112 出色的解决方案并简化评论链,让我们一一考虑您的需求(并且不按顺序):

  • 无碰撞

从技术上讲,这不是哈希函数。哈希函数是将异构、任意长度的数据输入映射到固定宽度、同质的输出。如果输入比输出长,实现这一点的唯一方法是通过一些数据丢失。对于大多数应用程序来说,这是可以容忍的,因为哈希函数仅用作快速查找键,并且代码会回退到较慢的完整数据比较。这就是为什么许多指南和语言坚持认为 如果实现一个,则必须实现另一个

幸运的是,你说:

  • 两个 UUID 输入 mn
  • 每个 UUID 都是 128 位
  • f(m,n)的输出必须为256位或更少

您的两个输入加起来正好是 256 位,这意味着您不必丢失任何数据。如果您需要较小的输出,那么您就不走运了。事实上,您可以将两个数字连接在一起并生成完美、独特的表示。

  • f(m,n)f(n,m) 必须生成相同的哈希值

为了实现这一最终要求,请根据两个 UUID 的某些内在值来决定串联顺序。建议的较小的优先效果非常好。然而...

  • 哈希值不需要是可逆的

如果您特别需要不可逆哈希,那完全是另一个问题。在输入加密哈希函数时,您仍然可以使用小于比较来确保顺序独立性,但是即使使用固定宽度输入和 256 位输出宽度,您也很难找到保证不会发生冲突的方法。


0
投票

这就是我用于满足这些要求的方法。

func generateUniqueString(stringsList []string) string {
    // Sort the strings to make order irrelevant
    sort.Strings(stringsList)

    concatenated := strings.Join(stringsList, ",")

    // Compute the hash
    hash := sha256.Sum256([]byte(concatenated))

    // Return the hash as a hexadecimal string
    return fmt.Sprintf("%x", hash)
}

stringsList
是字符串形式的 UUID 列表。

希望有帮助

© www.soinside.com 2019 - 2024. All rights reserved.