【问题标题】:Alternative to hexdigest that uses all 26 letters?替代使用所有 26 个字母的 hexdigest?
【发布时间】:2019-12-11 09:26:19
【问题描述】:

我正在编写一个调用各种 API 的应用程序。每个 API 都有自己的日志记录,我想让跟踪所有各种日志文件的事务变得容易。

为此,我在事务开始时创建一个唯一(ish)字符串,记录它,然后将该字符串传递给其他 API,以便它们都可以将其包含在日志记录中。

这是我正在使用的代码:

s = '%s %s' % (username, datetime.datetime.now())
token = hashlib.md5(s.encode('utf-8')).hexdigest()

这运行良好,但仍有改进的余地。 hexdigest()(显然)只使用十六进制字符,即0-9a-f。如果我偶尔遇到令牌冲突,我不会太在意,但我想尽可能避免它。有没有类似的函数可以使用全部 26 个字母?

【问题讨论】:

  • 这里可以选择 UUID 吗?
  • @SimeonVisser UUID 似乎具有仅使用十六进制数字的相同限制。
  • @PatrickArtner base64 为相似的输入产生相似的输出,这是我不想要的。
  • 您将两个不同的问题混为一谈。 1) 散列函数及其碰撞概率,以及 2) 对散列函数的结果进行编码。我不确定您真正关心的是哪个问题。
  • @JamesKPolk 我假设更大的输出地址空间会导致更少的哈希冲突。不是这样吗?

标签: python python-3.x hash md5


【解决方案1】:

尝试https://en.wikipedia.org/wiki/Ascii85 及其 URL 安全变体以获得更密集的表示。

当然,您必须对原始字节进行编码。 (另外,从加密的角度来看,MD5 是一个糟糕的选择,SHA2 更好。)

【讨论】:

  • 感谢您的回答 - 我不知道这一点。但我真的想要一个 hash 而不是 encoding 的东西——也就是说,我希望相似的输入产生截然不同的输出。
  • SHA2 是一种哈希算法,正如您所描述的那样。您正在使用用户名并在当前时间有效地对其进行加盐;这两部分都很容易猜到,因此可以创建像您这样的令牌。 OTOH,您似乎没有将其用于身份验证目的,因此 MD5 很好。
【解决方案2】:

您可以对数据进行哈希处理,然后使用 base64 对哈希进行编码,而不是直接获取十六进制摘要:

s = '%s %s' % (username, datetime.datetime.now())
digest = hashlib.md5(s.encode('utf-8')).digest()
token = base64.b64encode(digest)

这使用所有 26×2+10 = 62 个字母数字字符,加上 +/

您的实现可能会产生如下内容:

d88cc7dea0fee57975187d4b30950f7b

用base64编码会稍微减少长度:

2IzH3qD+5Xl1GH1LMJUPew==

然而,如果你想避免冲突,你需要增加摘要的长度——所以使用像 SHA512 这样的散列函数,而不是 MD5,甚至只是生成一个随机号码!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-27
    • 2021-12-10
    • 2023-04-04
    • 2020-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多