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

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

先感谢您。

最简单的方法是:

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

在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 

编辑

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

 base31 = ([*0..9,*'a'..'z'] - %w[aeiou]).join base52 = ([*0..9,*'a'..'z',*'A'..'Z'] - %w[aeiou AEIOU]).join 

但是,有了这个,你仍然会遇到AnyBase.encode(328059,base31)AnyBase.encode(345055,base31)AnyBase.encode(450324,base31) 。 因此,您可能希望避免使用类似元音的数字:

 base28 = ([*'0'..'9',*'a'..'z'] - %w[aeiou 0 1 3]).join base49 = ([*'0'..'9',*'a'..'z',*'A'..'Z'] - %w[aeiou AEIOU 0 1 3]).join 

这也可以避免“是0还是O?”的问题。 并且“那是1还是我?”。

我使用了有点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 

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

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

对于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