鉴于您不是散列每个url,而是一个模糊可预测的数字,您可以散列结果并取前 N 位
但是,有很多解决方案可以解决碰撞问题
- 忽略它们-它们将很少见(理想情况下)
- 选择下一个值
- 再次散列结果(使用您的输入)
- 增加返回字符串的大小
- ...
这是关于杜鹃散列的精彩视频(这是与此处相关的散列结构):
https ://www.youtube.com/watch?v=HRzg0SzFLQQ
这是 Python 中的一个示例,它从哈希中找到一个 8 个字符的字符串,该字符串应该是相当唯一的(然后可以将其收集到一个排序的数据结构中,将其映射到一个 URL)
这首先使用雪崩散列 ( SHA-265 ) 对值进行散列,然后循环查找它的最小值(从十六进制字符串的前面切片)以形成一个 8 字符的 base62 字符串
这可以变得更加有效(甚至,例如通过bisecting),但可能更清晰,并且很大程度上取决于未指定的算法要求
import hashlib
BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
m = hashlib.sha256()
m.update("https://stackoverflow.com/questions/65714033/tiny-url-system-design".encode())
digest = m.digest() # hash as bytes b',\xdb3\x8c\x98g\xd6\x8b\x99\xb6\x98#.\\\xd1\x07\xa0\x8f\x1e\xb4\xab\x1eg\xdd\xda\xd6\xa3\x1d\xb0\xb2`9'
hex_str = digest.hex() # string of hex chars 2cdb338c9867d68b99b698232e5cd107a08f1eb4ab1e67dddad6a31db0b26039
for hashlen in range(100, 1, -1):
number = int(hex_str[:hashlen], 16) # first_n_chars(str(hex)) -> decimal
val = ""
while number != 0:
val = "{}{}".format(BASE62[number % 62], val) # append new chars to front
number = number // 62 # integer division
if len(val) <= 8:
break
print(val) # E0IxW0zn
如何使用 Python3 修复 base62 编码的代码中的 base62逻辑?