如何在twitter中实现像网址一样的简短网址?

时间:2011-06-14 03:52:21

标签: ruby short-url

如果有一个长网址,我想生成一个像twitter中那样的简短网址,有没有办法在ruby中实现?

提前谢谢。

4 个答案:

答案 0 :(得分:61)

最简单的方法是:

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

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

    对基础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
    

    修改

    如果您想避免碰巧是英文单词的网址(例如,四个字母的发誓单词),您可以使用一组不包含元音的字符:

    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)AnyBase.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还是我?”。

答案 1 :(得分:12)

我使用bitly宝石。这很简单。

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

答案 2 :(得分:1)

您可以使用这么多网址缩短服务的API生成短网址。几乎所有的服务都为您提供了一个API,使您能够调用和缩短网址,这正是Twitter客户端的功能。您应该查看特定网址缩短服务的网站以获取更多详细信息。

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

答案 3 :(得分:1)

对于Ruby 2.0,请将解码方法替换为:

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