25

如果有一个长 URL,我想生成一个短 URL,就像 Twitter 中的那样。有没有办法在 Ruby 中实现这一点?

4

4 回答 4

63

最简单的方法是:

  1. 保留所有 URL 的数据库
  2. 当你在数据库中插入一个新的 URL 时,找出自增整数主键的 id。
  3. 将该整数编码为基数 36 或 62(数字 + 小写字母或数字 + 混合大小写字母)。瞧!你有一个短网址!

在 Ruby 中编码到 base 36/从 base 36 解码很简单:

12341235.to_s(36)
#=> "7cik3"

"7cik3".to_i(36)
#=> 12341235

编码为 base 62 有点棘手。这是一种方法:

module AnyBase
  ENCODER = Hash.new do |h,k|
    h[k] = Hash[ k.chars.map.with_index.to_a.map(&:reverse) ]
  end
  DECODER = Hash.new do |h,k|
    h[k] = Hash[ k.chars.map.with_index.to_a ]
  end
  def self.encode( value, keys )
    ring = ENCODER[keys]
    base = keys.length
    result = []
    until value == 0
      result << ring[ value % base ]
      value /= base
    end
    result.reverse.join
  end
  def self.decode( string, keys )
    ring = DECODER[keys]
    base = keys.length
    string.reverse.chars.with_index.inject(0) do |sum,(char,i)|
      sum + ring[char] * base**i
    end
  end
end

......它在行动:

base36 = "0123456789abcdefghijklmnopqrstuvwxyz"
db_id = 12341235
p AnyBase.encode( db_id, base36 )
#=> "7cik3"
p AnyBase.decode( "7cik3", base36 )
#=> 12341235

base62 = [ *0..9, *'a'..'z', *'A'..'Z' ].join
p AnyBase.encode( db_id, base62 )
#=> "PMwb"
p AnyBase.decode( "PMwb", base62 )
#=> 12341235

编辑

如果您想避免恰好是英语单词的 URL(例如,四个字母的脏话),您可以使用一组不包含元音的字符:

base31 = ([*0..9,*'a'..'z'] - %w[a e i o u]).join
base52 = ([*0..9,*'a'..'z',*'A'..'Z'] - %w[a e i o u A E I O U]).join

但是,这样您仍然会遇到诸如AnyBase.encode(328059,base31)orAnyBase.encode(345055,base31)或之类的问题AnyBase.encode(450324,base31)。因此,您可能还想避免类似元音的数字:

base28 = ([*'0'..'9',*'a'..'z'] - %w[a e i o u 0 1 3]).join
base49 = ([*'0'..'9',*'a'..'z',*'A'..'Z'] - %w[a e i o u A E I O U 0 1 3]).join

这也将避免“是 0 还是 O?”的问题。和“那是 1 还是 I?”。

于 2011-06-14T04:06:15.453 回答
12

我使用bitly gem。这真的很简单。

gem install bitly

# Use api version 3 or get a deprecation warning
Bitly.use_api_version_3

# Create a client
bitly = Bitly.new(username, api_key)

# Call method shorten
bitly.shorten('http://www.google.com').short_url
于 2011-06-14T07:45:34.497 回答
1

好吧,您可以使用众多 u​​rl 缩短服务的 API 来生成短 URL。几乎所有现有的服务都为您提供了一个 API,以便您能够调用和缩短 url,这正是 twitter 客户端所做的事情。您应该查看特定 url 缩短服务的网站以获取更多详细信息。

如果您想自己创建这样的服务,那也可以很简单,您需要做的就是在原始长 url 和特殊短 url(由您生成)之间维护一个内部映射(在数据库中) . 当您收到对特定短 url 的请求时,您应该能够从数据库中获取原始长 url 并将用户重定向到相同的位置。

于 2011-06-14T04:07:40.850 回答
1

对于 Ruby 2.0,将 decode 方法替换为:

def self.decode( string, keys )
  ring = DECODER[keys]
  base = keys.length
  string.reverse.chars.map.with_index.inject(0) do |sum,(char,i)|
    sum + ring[char] * base**i
  end
end
于 2013-12-29T19:40:21.050 回答