【问题标题】:Two-way encoding function that returns short hashes返回短哈希的双向编码函数
【发布时间】:2013-01-31 15:58:28
【问题描述】:

我们正在为我们的网站构建 URL 缩短功能。

我们现在想出什么:

  • 我们获取一个 URL (http://www.google.com) 并对其进行 sha1,最终得到一个 40 个字符的哈希 (738ddf35b3a85a7a6ba7b232bd3d5f1e4d284ad1)。
  • 我们采用 sha1 哈希并将其编码为 base62(基本上是 A-Z、a-z、0-9),最后得到一个 28 个字符的哈希 (jNMYchEoche67ro1k5gsCcHfDzmR),我们可以将其解码回原始 sha1。

我们使用 sha1 的原因是为了确保用户无法从当前/过去的 URL 中猜测下一个 URL。

我们使用 base62 的原因是为了使 URL 对用户有效且可读。

现在将附加到我们的域 (http://www.google.com/r/jNMYchEoche67ro1k5gsCcHfDzmRis) 的 28 个字符的“短 URL”有点太长了,尤其是考虑到 Twitter 的字符限制。

我们目前正在考虑将 sha1 减少大约 20 个字符,这将产生一个 14 个字符的短网址,但如果再继续下去,我们担心会太快遇到冲突。

我们也考虑过Compressing big number (or string) to small value,但这需要我们将 28 或 14 个字符的散列分成 2 部分并对这些部分进行排序,我们不知道如何从那里返回到原始散列。

有人知道我们能做什么吗?我们更喜欢不依赖数据库来构建 URL 的解决方案,但如果需要数据库,请记住我们仅限于 Redis / MongoDB(这意味着没有自动增量整数字段)。

【问题讨论】:

  • 请注意,您不能将任意 URL “压缩”为固定长度;您将需要某种查找(基本上是数据库)。那么您的问题真的是“如何生成唯一的短伪随机字符串?”?
  • 嗯,无论如何您都无法反转 sha1 哈希。那么你怎么知道原始 URL 是什么?
  • “愿意为冲突妥协”听起来像是一张通往地狱的单程票。至少与您在这里获得的相比:没有。不要重新发明轮子,而是使用现有的众多缩短 API 之一或使用您的应用生成正确工作的缩短 url 的方法(例如使用数据库)。
  • 但是无论如何都要插入到数据库中...
  • 不用担心 URL 长度和 Twitter - 它会缩短长 URL。在到达实际 URL 之前,您只需让用户 ping 通两个 URL 缩短器。

标签: java php math encoding character-encoding


【解决方案1】:

我不确定我是否理解您的所有要求,但这就是我的想法..

减少 sha1 似乎是正确的方法。

如果您在数据库中“注册”每个短 URL,则可以通过尝试在发生冲突时分配备用短 URL 来避免冲突(如果已在您的数据库中找到哈希,则存在冲突)。

它会像这样工作:

  1. 尝试分配一个新的哈希值,把 sha1 剪掉多少,结果就是 HASH1
  2. 检查 DB 中是否有冲突,没有冲突,在 DB 中注册 HASH1 并完成
  3. 如果发生冲突,请尝试分配一个新的哈希,例如通过将 sha1 减少一个字符(导致更长的哈希),我们有 HASH2 作为结果
  4. 检查碰撞..(步骤 2)等等

每次您想查找正确的长 URL 以获取哈希值时,您当然必须咨询您的数据库。我想这就是你现在已经在做的事情,因为 sha1 是不可逆的。

您最初应该将 sha1 削减多少?我会尽可能多地说,只要您满足您的要求,即很难猜测下一个 url。我想说只留下 5 个字节的 sha1(即 40 位)将很难猜到......(如果你的数据库中有 100 万个短 URL,它仍然会是百万分之一的猜测)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-10
    • 2016-12-30
    • 1970-01-01
    • 2014-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多