0

我有一个很大的 url,我想把它缩小成一个较小的 url。我已经在我的 rails 应用程序中实现了路由部分。现在棘手的部分是缩短实际网址。是否有推荐的算法将字符串缩短为一组元素(可能是数字和字符串的混合)


很抱歉没有举出一个例子。比如说我有"localhost:3000/orders/1". 我需要类似的东西"localhost:3000/:somesmallstring"


example.com/orders/1/show_video == exmpl.com/shortened_url 应该来到同一页面。我拥有这两个域。

TL; 还要考虑这个例子。假设我的网站有域名 example.com。我可以为我的网站使用缩短网址exmpl.com/shortened_url吗?我已经购买了这两个域。我应该为此在路由文件中进行哪些更改,以便它加载缩短模块以在仅来自不同域名时找到真实ID?有没有办法解决这个问题。

4

3 回答 3

0

是否有推荐的算法将字符串缩短为一组元素(可能是数字和字符串的混合)

根据sawa的评论,没有这样的算法。

如果您有一组有限的允许字符串,则可以枚举它们并以合适的基数表示该数字。Base 64 有一个众所周知且得到良好支持的“url 安全”版本,非常适合表示 URL 路径内的任意压缩数据。

例如,只需获取您的整数订单 ID,它就已经是可枚举的了。如果您可以安全地假设最大允许值是 32 位整数,我们可以将其编码如下:

require 'base64'
number_to_encode = 1_234_567_890
compact_string = [number_to_encode].pack('N*') # Network byte order
encoded = Base64.urlsafe_encode64( compact_string )
# => "SZYC0g=="

这采用了一个最多 10 位数字的 id,并从中创建了一个包含 8 个字符的 url 字符串。要将其解码回您需要的数字:

require 'base64'
string_to_decode = "SZYC0g==" # e.g. params[:order_id] from /o/:order_id
packed_string = Base64.urlsafe_decode64( string_to_decode )
number = packed_string.unpack('N*').first
# => 1234567890

原则上,您可以通过这种方法表达任何类型的数据,前提是您可以在相关控制器中对其进行解包和消除歧义。但是,压缩有限制。您不能采用任意 32 位整数的参数,并将其放入 5 个 base64 字符(因为每个 base64 字符最多是 6 位数据)。

如果您需要像在 bit.ly 或 tinyurl.com 上看到的短 URL,那么可以通过创建一个可能的 URL 的大型查找表,并以与上面类似的方式对该表中的每一行编码 id 来完成此操作。或者,您可以将此数据存储为每个模型的唯一索引,并将序列号放入该列,或者生成随机字符串以测试其唯一性。所有这些方法本质上归结为有一组有限的引用来解决,将其转换为一个数字(项目的实际计数,或者选择低于理论最大值的唯一值),并使用像 Base64 这样的编码方案来表示与使用基数 10 相比,它的字符数更少。

于 2013-10-08T14:06:48.513 回答
0

你可以使用Hash函数。例如,任何长度的每个字符串的 MD5 将是一个 32 字符的字符串。

但它不能保证您的 url 映射是唯一的。散列函数是单向函数,您不能反转该过程。

于 2013-10-08T10:34:55.107 回答
0

您可以尝试以这种方式解决:

路线.rb

  resources :authors, :path => "aut" do
    resources :articles, :path => "art"
  end

在命令行上运行 rake 路由会产生以下结果:

author_articles     GET    /aut/:author_id/art(.:format)          articles#index
                    POST   /aut/:author_id/art(.:format)          articles#create
new_author_article  GET    /aut/:author_id/art/new(.:format)      articles#new
edit_author_article GET    /aut/:author_id/art/:id/edit(.:format) articles#edit
author_article      GET    /aut/:author_id/art/:id(.:format)      articles#show
                    PUT    /aut/:author_id/art/:id(.:format)      articles#update
                    DELETE /aut/:author_id/art/:id(.:format)      articles#destroy
authors             GET    /aut(.:format)                         authors#index
                    POST   /aut(.:format)                         authors#create
new_author          GET    /aut/new(.:format)                     authors#new
edit_author         GET    /aut/:id/edit(.:format)                authors#edit
author              GET    /aut/:id(.:format)                     authors#show
                    PUT    /aut/:id(.:format)                     authors#update
                    DELETE /aut/:id(.:format)                     authors#destroy
于 2013-10-08T09:58:50.247 回答