【问题标题】:Paranoia secure UUID generation偏执狂安全 UUID 生成
【发布时间】:2017-10-06 22:33:11
【问题描述】:

我需要在分布式系统上生成许多唯一标识符。

  1. paranoia 模式下,我不确定:
    • 永远不会发生碰撞
    • 阻止确定计算机位置用于生成标识符(Mac 地址和日期时间)

我想生成 UUID。

  1. 如果我使用 UUID1(基于 MAC 地址、时间戳等):

    • 我确定永远不会发生碰撞
    • 可以找到位置
  2. 如果我使用 UUID4(基于随机生成器):

    • 有可能发生碰撞(发生碰撞的可能性真的非常非常小,但存在!
    • 我确定无法确定位置(日期和计算机)

你有满足这两个约束的解决方案吗?

【问题讨论】:

  • 您可能想查看this answer 链接到一些 Eric Lippert 帖子的链接。您是否真的查看过版本 4 下发生意外碰撞的几率?并将其与其他“极不可能”的情况放在一起?
  • this answer:“...... GUID 碰撞的几率小于宇宙射线在计算机内存中翻转一点并搞砸任何“准确”给出的答案的几率你想运行的算法”
  • 你好,我同意这个理论,但只是为了好玩,我希望找到一个 paranoia 解决方案。
  • 简而言之:使用任何去中心化算法总是有可能发生冲突。即使使用 UUID1,您也取决于 MAC 地址的唯一性和时间的正确性(不是给定的)。 UUID4 已经非常好。统计数据和(不)可能性是一件可怕且不直观的事情。你只是比你需要的更偏执。
  • 我投票结束这个问题,因为 StackOverflow 的范围仅限于实用、可回答的问题。拒绝接受的最佳实践(以及它们背后的统计数据)使这本质上是一个不切实际的要求。

标签: python uuid


【解决方案1】:

也许我们可以将 UUID1 与由“秘密”密钥确定的“静态排列”函数结合起来? 函数必须是双射的。

灵感来自:http://code.activestate.com/recipes/126037-getting-nth-permutation-of-a-sequence/

def getPerm(seq, index):
    "Returns the <index>th permutation of <seq>"
    seqc= list(seq[:])
    seqn= [seqc.pop()]
    divider= 2 # divider is meant to be len(seqn)+1, just a bit faster
    while seqc:
        index, new_index= index//divider, index%divider
        seqn.insert(new_index, seqc.pop())
        divider+= 1
    return "".join(seqn)


secret=123456**123456 # a big secret integer

secure_id=getPerm("af5f2a30-aa9e-11e7-abc4-cec278b6b50a",secret)
# "1-a-faa4cba8c5b0ae372a72-ec-1fb9560e" ==> Same character, just change order

secure_id=getPerm("aaaaaaa0-bbbb-cccc-xxxx-yyyyyyyyyy0y",secret)
# "c-b-axaxxybyyyx0ybacyaya-cy-caybay0y" ==> Same secret => Same permutation  (check position of caracter '0' and '-')

我们可以通过保留'-'字符的位置来改进排列“混淆”

【讨论】:

  • secret 被泄露的几率我认为远远高于第 4 版意外碰撞的几率——这样的泄露违反了“计算机位置”要求。
  • UUID4 很好看。我有一个 UUID1 的变化。对于秘密的可能性,我可以随机生成它并在 ID 的前缀中使用秘密的哈希值。这样没人没有秘密!但是,通过这种方式,我可能会重新引入碰撞概率......
【解决方案2】:

也许我们可以简单地对 UUID 进行编码,使用 Base64 来轻松传输/存储 ID。 编码也是一个双射函数。

import base64

def encode(string,key):
    encoded_chars = []
    for i in xrange(len(string)):
        key_c = key[i % len(key)]
        encoded_c = chr((256 + ord(string[i]) + ord(key_c)) % 256)
        encoded_chars.append(encoded_c)
    encoded_string = "".join(encoded_chars)
    return base64.urlsafe_b64encode(encoded_string)

def decode(encoded_string,key):
    decoded_chars = []
    string=base64.urlsafe_b64decode(encoded_string)
    for i in xrange(len(string)):
        key_c = key[i % len(key)]
        decoded_c = chr((256 + ord(string[i]) - ord(key_c)) % 256)
        decoded_chars.append(decoded_c)
    encoded_string = "".join(decoded_chars)
    return "".join(decoded_chars)

secure_id=encode("af5f2a30-aa9e-11e7-abc4-cec278b6b50a","secret")
# "1MuY2JfVppWQ08at2JKUo8qroMbF1Zmh1srGpJys1ZvFp5XV"

uuid=decode(secure_id,"secret")
# "af5f2a30-aa9e-11e7-abc4-cec278b6b50a"

这样一来,我总是有秘密问题。

(注意:我们不需要解码功能)

【讨论】:

    猜你喜欢
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-04
    • 2021-10-16
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    相关资源
    最近更新 更多