2009-06-06 59 views
0

我的工作涉及的URL「轉發」項目(如bit.ly和tinyurl.com,但我們並不真正需要的是短)。加密在Ruby和字母數字

對於這一點,我需要「生成」字母數字串(我想明確字母和數字)映射到每個URL。其中一個選項會生成一個隨機字符串並將其存儲在某個地方。但是,我想避免使用數據庫,因爲我們在應用程序中沒有使用任何數據庫。我想實際上「編碼」的網址,以便它可以稍後解碼。

有關如何做到這一點的任何提示?

回答

2

無法完成。一個任意的URL包含很多字符 - 比方說100.一個縮短的URL可能包含5.你不能使用5個字符來重建100沒有某種查找表;沒有足夠的信息可以做到。

編輯1:好吧,如果你實際上並不需要一個URL 縮短服務(?那麼爲什麼你寫的),有很多的選擇。我會使用普通的Base64編碼,也許在通過zlib或其他壓縮器之後(這可能會使URL更長;如果有幫助,您將不得不測量)。

編輯2:標準的Base64確實使用三個非字母數字字符:+/,並-。如果這些是不可接受的,你有幾個選擇:

  1. 修改Base64。 Wikipedia suggests「修改的Base64 URL」,它丟棄所有=並取代+/分別-_。但那些仍然不是字母數字,這不會幫助你。

  2. 一些臨時計劃,像Base32或Base36。如果你知道Base64是如何完成的,那麼這很容易實現(見上面的鏈接)。 (編輯3:我想Base32實際上是standardized貌似RFC 4648 Base32與8填充,而不是=填充會工作得很好了你)。

  3. 一些半標準方法。有很多可能性。不幸的是,他們中的大多數都依賴於幾個特殊的非字母數字字符,只是因爲通過使用少至一到兩個字符就可以獲得更優異的性能。看看Binary-to-text encoding以獲得更好的調查結果。

+0

嗯......我不真正關心,如果是短或不...重要的是,它需要在自己「保持」 THR原單URL。我們主要使用它來跟蹤點擊次數。 – 2009-06-06 22:17:04

+0

對不起,從開始不清楚enoigh ...我試圖使用Base64 ...問題是,它添加非字母字符,如%。有什麼辦法擺脫它們? 感謝您的幫助! – 2009-06-06 22:22:11

0

一個簡單的方法來做到這一點是要列出非字母數字字符允許的URL的所有符號 - !我想出了一個快速的互聯網搜索的有$ -_ + *」 (); /?:@ = & - 只是以某種方式編碼。我的列表中有17個符號,並對其進行編碼而不放棄可讀性,我能想到的是選擇一個字母數字符號的最簡單的方法,說S,充當移位碼:

$ ⇒ s0 - ⇒ s1 _ ⇒ s2 . ⇒ s3 + ⇒ s4 ! ⇒ s5 
* ⇒ s6 ' ⇒ s7 (⇒ s8 ) ⇒ s9 ; ⇒ sa /⇒ sb 
? ⇒ sc : ⇒ sd @ ⇒ se = ⇒ sf & ⇒ sg s ⇒ ss 

另一種方法是將原始URL轉換爲比特流,最好使用某種壓縮算法,因爲您已經放棄了易讀性,然後爲每個可能的6位序列分配一個字母數字符號。請注意,這會留下4個字母數字符號,您從不使用 - 如果您真的關心長度,可以回收它們,但似乎並不值得使用這種併發症。

我會忽略該主題中的「加密」單詞,因爲您似乎並沒有對使該方案難以發現感興趣。

3

我想,我居然找到一個更好的解決方案(至少是更合適,更容易在我的情況下實現的)

這在某種程度上它由unpackking與H *參數字符串的黑客。 下面是代碼樣本:

url = "http://stackoverflow.com/questions/960658/crypto-in-ruby-and-alphanumeric" 
unpacked = url.unpack("H*") # => 687474703a2f2f737461636b6f766572666c6f772e636f6d2f7175657374696f6e732f3936303635382f63727970746f2d696e2d727562792d616e642d616c7068616e756d65726963 
unpacked.pack("H*") # => http://stackoverflow.com/questions/960658/crypto-in-ruby-and-alphanumeric 

我不會紀念這個作爲回答(甚至不知道我可以...),但我想,讓讀者知道,它實際上做了騙我;)

0

只要你不介意醜陋的網址,你可以做一個快速與Base64和URL轉義:

require 'base64' 
require 'cgi' 
require 'uri' 

def encode_url(url) 
    CGI.escape(Base64.encode64(url)) 
end 

,然後再返回:

def decode_url(encoded_url) 
    Base64.decode64(CGI.unescape(encoded_url)) 
end 

又大又醜的網址,但它會完成這項工作:

說遇到此頁面
>> u = encode_url("http://railsruby.blogspot.com/2006/07/url-escape-and-url-unescape.html") 
=> "aHR0cDovL3JhaWxzcnVieS5ibG9nc3BvdC5jb20vMjAwNi8wNy91cmwtZXNj%0AYXBlLWFuZC11cmwtdW5lc2NhcGUuaHRtbA%3D%3D%0A" 
>> decode_url u 
=> "http://railsruby.blogspot.com/2006/07/url-escape-and-url-unescape.html"