8

我想编写一个不必使用数据库的 URL 缩短器。相反,为了尽可能少地移动部分,脚本将根据算法为我的 URL 创建一个唯一的哈希(如 md5,除了 md5 太长)。我不太确定我会怎么做。有什么建议吗?

如果这很重要,我更愿意用 Ruby 编写它。

4

4 回答 4

2

您可以使用一些可用于将 URL 转换为模糊内容的字符串操作工具来执行此操作,但是正如您在问题中指出的那样,您从中获得的 url 将比 url 缩短器的典型长度更长。

url 的压缩效果不是很好。

于 2011-01-27T15:51:17.867 回答
2

您需要的是一种压缩和解压缩字符串的方法。生成的压缩版本也是一个字符串。这几乎是不可能的,因为 URL 已经很短了。对于大多数 URL,编码和无损压缩总是会增加最小的开销,这将导致字符串大于原始字符串。

但是,对于很长的 URL,它可能会起作用。

因此,最后,您几乎总是需要存储(数据库)中的查找表。

Base64 是最合乎逻辑的解决方案。然而,就其本身而言,对于短字符串(通常是 URL),Base64 编码返回比原始字符串更长的字符串;由于填充,主要是。因此,我们还将尝试使用 zlib 来压缩字符串。

require "uri"
require "base64"
require "zlib"

shortner_url = URI.parse("https://s.to")
long = "https://stackoverflow.com/questions/4818429/url-shortener-with-no-database"
url = URI.parse(long) 
stripped = url.host + url.path
stripped.length #=> 66

# Let's see that Base64 on its own does not shorten the url.
encoded = Base64.encode64(stripped)
encoded.length #=> 90

# So, using zlib. To compress.
compressed = Zlib::Deflate.deflate(stripped)
encoded = Base64.encode64(compressed)
encoded.length #=> 94 
# It became worse.

# Now, with a long url (they can be much longer even), in a oneliner; to simplify omit the stripping part:
long = "http://www.thelongestlistofthelongeststuffatthelongestdomainnameatlonglast.com/wearejustdoingthistobestupidnowsincethiscangoonforeverandeverandeverbutitstilllookskindaneatinthebrowsereventhoughitsabigwasteoftimeandenergyandhasnorealpointbutwehadtodoitanyways.html"
long.length #=> 263
Base64.encode64(Zlib::Deflate.deflate(long)).length #=> 228

# In order to turn this into a valid short URL, however, we need `urlsaf_encode64()`

shortner_url.path = "/" + Base64.urlsafe_encode64(Zlib::Deflate.deflate(long))
shorther_url.to_s #=> "https://s.to/eJxNjkEWwyAIRG-U7HsbElFpEPIE68vti6t2BcwbZn51v1_7PufcvCKrFDRnMtf8u81HzuA_IWkDEoGG4EtiMN9ObftE6Pgey0FSvK6gIx7GTUl0GsmJSz1Biqpk7fjBDpL-xjGcopKYWfWyiySBRBFJABw9UnB9xaWj1LDCQWUGAQYzBVLECPbyxFLBJDqA7-DxSJ5YIbkGnoM8Ex7bqjf-AiodbYM="
 shortner_url.to_s.length #=> 237 WE SAVED 26 characters!

剥离注意事项:可以去掉'https://'。Real 实现需要在字符串中添加一段,以确定 https 或 http:'1'+result 用于 https,'0'+result 用于 http。另一个“hack”是让 url-shortening 服务使用 http 作为 http url,使用 https 作为 https url。

如果您始终拥有相同的域,则也可以忽略域部分。

如果您有很多斜杠或其他重复字符(如破折号),则压缩效果更好。

于 2019-07-31T18:27:10.047 回答
1

最终,如果您使用的是短链接,您只需要生成一个适当易读的唯一代码(尝试省略类似的字母/数字,例如零和“o”,以防某些可怜的虫子实际上必须输入它)并关联该代码在某种形式的商店中具有原始 URL。

虽然我可以理解您为什么不想使用数据库,但在许多方面它是一种完美的存储形式,尤其是当您查看专用键/值存储之一时,例如CassandraRedisMongoDB等。(那说,如果你在不熟悉的领域,一个简单的“传统” SQL 数据库可能是一个简单的第一步。)

于 2011-01-27T15:55:05.310 回答
0

如果不在某种数据库中查找,您将无法从哈希码解析原始 URL。

在没有数据库的情况下,您唯一能做的就是压缩 URL,然后在解析 URL 时解压缩。

严格来说,我想你可以对 URL 进行哈希处理。但是,如果您无法将其解析回原始 URL,那可能有什么价值呢?

于 2011-01-27T15:48:01.503 回答