我想编写一个不必使用数据库的 URL 缩短器。相反,为了尽可能少地移动部分,脚本只会根据算法(如 md5,但 md5 太长)为我的 URL 创建一个唯一的哈希值。我不太确定我会如何去做这件事。有什么建议吗?
如果重要的话,我更愿意用 Ruby 编写。
您需要的是一种压缩和解压缩字符串的方法。生成的压缩版本也是一个字符串。这几乎是不可能的,因为 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://”。真正的实现需要在字符串中添加一个片段,以确定 https 或 http:“1”+结果表示 https,“0”+结果表示 http。另一个“黑客”是让 url 缩短服务使用 http 作为 http url,使用 https 作为 https url。
如果你总是有相同的域名,你也可以忽略域名部分。
如果有很多斜杠或其他重复字符(例如破折号),压缩效果会更好。
您可以使用几个可用于将 URL 转换为模糊内容的字符串操作工具来完成此操作,但是正如您在问题中指出的那样,您通过这样做获得的 url 会比 url 缩短器的典型长度更长。
url 的压缩效果不太好。
如果不在某种数据库中查找,您将无法从哈希码解析原始 URL。
在没有数据库的情况下,您唯一能做的就是压缩 URL,然后在解析 URL 时解压缩。
严格来说,我猜你可以只对 URL 进行哈希处理。但如果您无法将其解析回原始 URL,那会有什么价值呢?
这是一个无数据库的解决方案,易于安装和管理。 https://github.com/kimili/No-DB-URL-Shortener
希望有帮助。