2011-06-14 13 views

Odpowiedz

59

Najprostszym sposobem jest:

  1. zachować bazę danych wszystkich adresów URL
  2. po włożeniu nowego adresu URL do bazy danych, dowiedzieć się identyfikator klucza podstawowego całkowitą autoinkrementacja.
  3. kodują tę liczbę całkowitą do podstawy 36 lub 62 (cyfry + mała litera alfabetu lub cyfry + mieszana litera alfa). Voila! Masz krótki adres URL!

Kodowanie do podstawy 36/dekodowania z podstawy 36 jest prosty w Ruby

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

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

Kodowanie oparcie 62 jest nieco Tricker. Oto jeden ze sposobów, aby to zrobić:

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 

... i to jest tutaj w akcji:

base36 = "abcdefghijklmnopqrstuvwxyz" 
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 

Edytuj

Jeśli chcesz uniknąć adresy URL, które stało się angielskich słów (na przykład czteroliterowe przekleństwa) można użyć zestawu znaków, które nie zawierają samogłosek:

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 

Jednak z tym nadal masz problemy, takie jak AnyBase.encode(328059,base31) lub AnyBase.encode(345055,base31) lub AnyBase.encode(450324,base31). Można w ten sposób chcą uniknąć numery samogłoski, jak również:

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 

Będzie to również uniknąć problemu „Czy to 0 lub O?” i "Czy to jest 1 czy ja?".

+5

masz pomógł mi wiele razy, naprawdę wdzięczni za pomoc, odpowiedź za każdym razem, gdy oferta jest świetna, dziękuję bardzo dużo . – ywenbo

+1

Uważaj na tę implementację, ponieważ generuje czytelne dla człowieka słowa, których możesz chcieć uniknąć. Na przykład. 645860.to_s (36) = "kaczka". 739172 można uznać za nieco gorszy. Polecam iść z base20 (0-9a-j) lub podobnym. Aby pomóc w podjęciu decyzji, możesz nawet użyć wyszukiwarki anagramów, takiej jak "gra słów", jak np .: 'wordplay 'aaabbbcccdddeeefffggghhhiiijjj'' - pokazuje, które słowa można wygenerować. – user569825

+0

@ user569825 Dzięki za notatkę (choć wydaje się to niewłaściwym powodem do zgonu). Sugerowałbym prawdopodobnie podstawowy zestaw znaków bez samogłosek w prostszy i mniej uderzający sposób. – Phrogz

1

Cóż, można wygenerować krótkie adresy URL za pomocą interfejsów API wielu usług skracania adresów URL. Prawie wszystkie usługi, które są dostępne, zapewniają interfejs API, dzięki któremu można wywoływać i skracać adresy URL, tak samo robią klienci Twittera. W celu uzyskania szczegółowych informacji należy zapoznać się ze stroną internetową poświęconą skróceniu adresu URL.

Jeśli chcesz utworzyć taką usługę na własną rękę, to może być całkiem proste, wystarczy zachować wewnętrzne mapowanie (w bazie danych) między oryginalnym długim adresem URL i specjalnym krótkim adresem URL (generowane przez ciebie). Po otrzymaniu prośby o określony krótki URL, powinieneś być w stanie uzyskać oryginalny długi URL z bazy danych i przekierować użytkownika do tego samego.

11

Używam klejnotu bitly. To naprawdę proste.

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 
1

Ruby 2.0, zastąpić metodę dekodowania przez:

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