【问题标题】:should we use the named based GUID for key identification purpose?我们应该使用基于命名的 GUID 来进行密钥识别吗?
【发布时间】:2014-01-27 18:58:08
【问题描述】:

现在,我们正在寻找为某些字符串值(文件 URL)生成一些唯一且确定性的 ID。基于此链接How to Create Deterministic Guids,看起来我们可以基于 MD5 哈希或 Sha1 哈希(类型 3 或类型 5,请参阅 GUID wiki page)创建 GUID。我也在互联网上进行了一些搜索,我认为它几乎相同,基本上是基于哈希生成一个确定性的 GUID。

当我第一次看到它时,它看起来很棒,但是我仍然不愿意将它用作识别某些东西的关键。我认为一般hash是用来检查的:

  1. 2个字符串是否匹配,不泄露原字符串内容
  2. 某些字符串/文件内容是否改变

这里,即使hash值发生冲突,也不是很好,但没关系,一旦数据再次更改,它会自我纠正,不会覆盖其他不相关的数据。但是,如果我们使用哈希作为主键来识别某些数据,那么冲突将意味着我们将覆盖一些不相关的数据,一旦发生覆盖就无法自我纠正。

所以在我看来,我们应该在这里使用数据库来真正生成确定性 GUID,而不是依赖 Hash:

  1. 在数据库中有一个包含 2 列的表:str_val、guid_val。 str_val 是PK
  2. 如果我们需要为 string1 生成一个 guid,我们会尝试在表中找到记录
  3. 如果我们能找到指南,我们就完成了。
  4. 如果找不到 guid,我们会执行插入逻辑。如果插入失败,很可能是因为其他线程只插入了一个,但可能没关系,因为插入竞争很少发生。

就在我要发布我的问题之前,我看到了这个 stackoverflow 帖子:How safe is it to rely on hashes for file identification?,它使用哈希作为文件标识,接受的答案认为可以使用哈希作为密钥。再一次,我觉得我在这里仍然需要更多的说服力。

如果有人能提供更多建议,将不胜感激。

【问题讨论】:

标签: c# .net guid uuid


【解决方案1】:

在这种情况下谈论 GUID 或 UUID 令人困惑。

关键是

  1. 输入的函数(散列,无论是“确定性 GUID”还是其他)或;
  2. 独立于输入,例如随机 GUID 或自动增量 ID
范围(所有可能的输出)小于域(所有可能的输入)的

所有哈希将由于Pigeonhole Principle 而发生冲突。但是,我们的想法是使用适当的哈希值,即improbable for a collision to occur,这在链接的问题中进行了讨论。

Cryptographic hash functions 还有其他目标,例如“不可行找到两个具有相同哈希值的不同消息。” (也就是说,即使有人 尝试,产生冲突仍然是不切实际的 - MD5 在这里失败并被认为是损坏的;而 SHA-1 一直是superseded by SHA-2。)

如果 Key 与数据独立(例如,不是哈希),那么我们不妨使用自动递增 ID - 它是确定性的,尽管独立于数据,并且保证唯一由数据库 - 收工。


因此,使用散列,密钥是一种标识数据自然密钥。这使得使用 just 哈希查询数据库成为可能。而且,如果我们相信客户端从现有数据生成散列,那么通常可以假设客户端拥有导致散列的数据。

在使用“独立确定性值”时,Key 是一个 Surrogate Key,用于标识 tuple。在这种情况下,如果“ID”未知,我们需要查询数据以找到合适的数据。这当然要求客户端在此类查询中使用原始数据。

这两种方法在适当的上下文中都是有效的,我在数据库设计中都使用了这两种方法。 (我一般更喜欢 Candidate Keys 来强加多重性,但结果是一样的。)


【讨论】:

  • 当域小于范围或范围小于域时是否会发生冲突?而“少”是指集合中的元素数量,也许澄清这一点会很有用。
  • 谢谢@user2864740,我明白了。我想这确实是一个判断电话,我们的解决方案是否可以承受碰撞,尽管可能性很小。在stackoverflow.com/questions/5525215/… 的帖子中,还有另一个答案也指出了这一点。
  • @windfly2006 这个想法是碰撞的可能性不可能很小。比如,发生碰撞的可能性比被流星撞击的可能性小。见Hash Collision Probabilities底部的表格。
  • @windfly2006 即使 GUID 也有同样的重复“机会” - 所以归结为:数据的 hash 是否应该被公开,或者应该是一个 任意唯一的ID 暴露?如果散列被暴露,人们可以尝试对他们自己生成的散列进行“探测攻击”。
  • 感谢@user2864740,我认为 GUID(类型 1)与 GUID(类型 3/5)相比应该有更少的重复机会。但是我确实得到了你的观点。非常感谢。
【解决方案2】:

您可以使用刻度从时间中获取唯一名称。我同时使用了刻度和随机字符串,然后将两者连接起来并为我的文件获取一个唯一的字符串名称。希望对你有帮助

http://msdn.microsoft.com/en-us/library/system.datetime.ticks(v=vs.110).aspx

【讨论】:

  • 我们希望在任何给定时间为同一个文件 URL 获取相同的 GUID,因为同一个文件 URL 应该只有一条记录。所以我不确定上述方法是否可行。
  • 我认为创建 guid 时会考虑时间。我担心你是否可以重新创建一个 guid。
  • 对不起,我想我没有说清楚。我们希望能够为相同的文件 URL 创建相同的 GUID。
猜你喜欢
  • 2011-06-23
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多