我想编写一个不必使用数据库的 URL 缩短器。相反,为了尽可能少地移动部分,脚本将根据算法为我的 URL 创建一个唯一的哈希(如 md5,除了 md5 太长)。我不太确定我会怎么做。有什么建议吗?
如果这很重要,我更愿意用 Ruby 编写它。
我想编写一个不必使用数据库的 URL 缩短器。相反,为了尽可能少地移动部分,脚本将根据算法为我的 URL 创建一个唯一的哈希(如 md5,除了 md5 太长)。我不太确定我会怎么做。有什么建议吗?
如果这很重要,我更愿意用 Ruby 编写它。
您可以使用一些可用于将 URL 转换为模糊内容的字符串操作工具来执行此操作,但是正如您在问题中指出的那样,您从中获得的 url 将比 url 缩短器的典型长度更长。
url 的压缩效果不是很好。
您需要的是一种压缩和解压缩字符串的方法。生成的压缩版本也是一个字符串。这几乎是不可能的,因为 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。
如果您始终拥有相同的域,则也可以忽略域部分。
如果您有很多斜杠或其他重复字符(如破折号),则压缩效果更好。
如果不在某种数据库中查找,您将无法从哈希码解析原始 URL。
在没有数据库的情况下,您唯一能做的就是压缩 URL,然后在解析 URL 时解压缩。
严格来说,我想你可以对 URL 进行哈希处理。但是,如果您无法将其解析回原始 URL,那可能有什么价值呢?