我想创建一个 URL 缩短服务,您可以在其中将长 URL 写入输入字段,该服务将 URL 缩短为“ http://www.example.org/abcdef”。
http://www.example.org/abcdef
除了 ” abcdef” 之外,还可以有任何其他包含 6 个字符的字符串a-z, A-Z and 0-9。这使得有 56~570 亿个可能的字符串。
abcdef
a-z, A-Z and 0-9
我的做法:
我有一个包含三列的数据库表:
然后我会将长 URL 插入表中。然后我会为“”选择自动增量值id并构建它的哈希值。然后应将此哈希作为“ short”插入。但是我应该建立什么样的哈希?像 MD5 这样的哈希算法会创建太长的字符串。我不使用这些算法,我想。自建算法也可以。
id
short
我的点子:
对于 ” http://www.google.de/” 我得到自动增量 id 239472。然后我执行以下步骤:
http://www.google.de/
239472
short = ''; if divisible by 2, add "a"+the result to short if divisible by 3, add "b"+the result to short ... until I have divisors for a-z and A-Z.
这可以重复,直到这个数字不再可整除。你认为这是一个好方法吗?你有更好的主意吗?
由于对这个主题的持续兴趣,我在 GitHub 上发布了一个有效的解决方案,其中包含JavaScript、PHP、Python和Java的实现。如果您愿意,请添加您的解决方案:)
我会继续你的“将数字转换为字符串”的方法。 但是,如果您的 ID 是素数且大于 52 ,您将意识到您提出的算法将失败。
你需要一个双射函数 f 。这是必要的,以便您可以为 f(123) = ‘abc’ 函数找到反函数g ( ‘abc’) = 123 。这意味着: __
[a-zA-Z0-9]
对于此示例,我将使用 125 10(125 以 10 为底)。
125 10 = 2×62 1 + 1×62 0 =[2,1]
[2,1]
这需要使用整数除法和取模。一个伪代码示例:
digits = [] while num > 0 remainder = modulo(num, 62) digits.push(remainder) num = divide(num, 62) digits = digits.reverse
现在将 索引 2 和 1 映射到您的字母表。这就是您的映射(例如使用数组)的样子:
0 → a 1 → b ... 25 → z ... 52 → 0 61 → 9
使用 2 - c 和 1 - b,您将收到 cb 62作为缩短的 URL。
http://shor.ty/cb
反过来更容易。您只需在字母表中进行反向查找。
e9a 62 = [4,61,0]= 4×62 2 + 61×62 1 + 0×62 0 = 19158 10
[4,61,0]
WHERE id = 19158