ruby - personalizado - personalizar url
¿Cómo implementar un url corto como urls en twitter? (4)
Si hay una url larga, quiero generar una url corta como las de twitter, ¿hay alguna forma de implementar en ruby?
Gracias de antemano.
Bien, podría generar URL cortas utilizando las API de tantos servicios de acortamiento de URL. Casi todos los servicios que existen ofrecen una API para que pueda invocar y acortar las URL, así es exactamente como lo hacen los clientes de Twitter. Para obtener más información, consulte el sitio web del servicio de acortamiento de url en particular
Si desea crear un servicio de este tipo por su cuenta, que también puede ser bastante simple, todo lo que necesita hacer es esencialmente mantener una asignación interna (en una base de datos) entre la URL larga original y una URL corta especial (generada por usted) . Y cuando recibe una solicitud para una URL corta en particular, debe poder obtener la URL larga original de la base de datos y redirigir al usuario a la misma.
La forma más fácil es:
- mantener una base de datos de todas las URL
- cuando inserte una nueva URL en la base de datos, averigüe el ID de la clave primaria de entero auto-incrementada.
- codifique ese entero en la base 36 o 62 (dígitos + alfa en minúsculas o dígitos + mayúsculas y minúsculas). Voila! Tienes un url corto!
Codificar a base 36 / decodificar desde base 36 es simple en Ruby:
12341235.to_s(36)
#=> "7cik3"
"7cik3".to_i(36)
#=> 12341235
La codificación a la base 62 es un poco engañosa. Aquí hay una forma de hacerlo:
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
... y aquí está en acción:
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
Editar
Si desea evitar las URL que son palabras en inglés (por ejemplo, palabras de jurado de cuatro letras) puede usar un conjunto de caracteres que no incluya vocales:
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
Sin embargo, con esto todavía tiene problemas como AnyBase.encode(328059,base31)
o AnyBase.encode(345055,base31)
o AnyBase.encode(450324,base31)
. Por lo tanto, es posible que también desee evitar los números vocálicos:
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
Esto también evitará el problema de "¿Es eso un 0 o una O?" y "¿Es eso un 1 o un I?".
Para Ruby 2.0, reemplace el método de decodificación por:
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
Yo uso la gema bitly Es realmente simple
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