我想创建一个URL缩短服务,您可以在其中将长URL写入输入字段,然后该服务将URL缩短为“ http://www.example.org/abcdef”。
http://www.example.org/abcdef
除了“ abcdef”以外,还有其他任何包含六个字符的字符串a-z, A-Z and 0-9。这使得56〜570亿个可能的字符串。
abcdef
a-z, A-Z and 0-9
我的方法:
我有一个包含三列的数据库表:
然后,我将长网址插入表中。然后,我将为“ 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