Ruby和Alphanumeric中的加密

时间:2009-06-06 22:05:15

标签: ruby url encoding

我正在开发一个涉及网址“转发器”的项目(比如bit.ly或tinyurl.com,但我们并不需要它简短。)

为此,我需要“生成”字母数字字符串(我明确需要字母数字)来映射到每个网址。其中一个选项是生成随机字符串并将其存储在某处。但是,我想避免使用数据库,因为我们的应用程序中没有使用任何数据库。我想实际“编码”网址,以便以后解码。

有关如何操作的提示吗?

5 个答案:

答案 0 :(得分:4)

我认为我实际上找到了一个更好的解决方案(在我的情况下至少更合适且易于实施)

它在某种程度上是一个黑客,包括用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

我不会将此标记为答案(甚至不能确定我可以......),但我想让读者知道它实际上对我有用;)

答案 1 :(得分:2)

无法完成。一个任意的URL包含许多字符 - 比方说100个。缩短的URL包含5个。如果没有某种查找表,你不能使用5个字符重建100个字符;没有足够的信息可以做到。

编辑1:好吧,如果你实际上并不需要一个URL 缩短(那么你为什么写这个?),有很多选择。我可能会使用普通的Base64编码,可能是在通过zlib或其他压缩器之后(可能会使URL更长;你必须测量它是否有用)。

编辑2:标准版Base64确实使用了三个非字母数字字符:+/-。如果这些是不可接受的,您有几个选择:

  1. 修改后的Base64。 Wikipedia suggests“修改了Base64 for URL”,删除了所有=,并分别用+/替换-_。但那些仍然不是字母数字,这对你没有帮助。

  2. 一些特殊方案,如Base32或Base36。如果您知道Base64是如何完成的,那么这很容易实现(参见上面的链接)。 (编辑3:我猜Base32实际上是standardized。看起来像RFC 4648 Base32 8填充而不是=填充对你来说会很好用。)

  3. 一些半标准的方法。有很多可能性。不幸的是,它们中的大多数依赖于几个特殊的非字母数字字符,仅仅因为通过使用少至一个或两个以上的字符,您可以获得更好的性能。请查看Binary-to-text encoding以获得比我能给出的更好的调查。

答案 2 :(得分:1)

遇到此页面的大多数人可能正在寻找使用Ruby生成TinyURL样式字符串的方法。 (这就是我找到它的方式。)

好消息是它非常简单。

# timestamp
>> DateTime.now.hash.abs.to_s(36)
=> "5ynfka" 

# invite code
>> "joe@momma.org".hash.to_s(36)
=> "emhs98"

基于http://blog.internautdesign.com/2007/11/2/base-conversion-and-tiny-url-type-hashes-in-ruby

答案 3 :(得分: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个字母数字符号 - 如果您真的关心长度,可以回收它们,但这似乎不值得复杂化。

我会忽略主题中的“加密”字样,因为您似乎并不感兴趣使该方案难以发现。

答案 4 :(得分:0)

只要您不介意丑陋的网址,您就可以快速使用base64和网址转义:

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"