我希望在我的应用中为ID做一个简单的混淆/缩短。为此,我想将整数映射到字符串,反之亦然。
我可以轻松地与to_i
和to_s
轻松互换:
>> 635.to_s(36)
# => "hn"
>> "hn".to_i(36)
# => 635
这考虑了0-9和a-z,但我还想考虑A-Z(大写),它在功能上等同于to_s(62)
。
在Ruby和/或Rails中有一种简单的方法吗?
修改
如果可能,我想用0-9,a-z和A-Z这样做。字符串需要对网址友好,并且我使用其他字符如-
来分隔网址中的值,因此最好避免使用这些字符。
答案 0 :(得分:2)
你可以使用基数58.有一个宝石:http://rubygems.org/gems/base58
require 'base58'
Base58.encode(12345) # => 4ER
Base58.decode('4ER') # => 12345
正如评论中所指出的,这会遗漏潜在的矛盾字符,例如I
,l
,0
和O
。
答案 1 :(得分:1)
原来有一个叫做base62的宝石完全符合我的描述:
https://github.com/jtzemp/base62
require 'base62'
>> 635.base62_encode
=> "AF"
>> "AF".base62_decode
=> 635
我还使用一个可以混合到任何需要混淆/缩短的模型的模块中使用了特定于rails的模块:
module AdditionalMethods
module Shortener
def short_id
self.id.base62_encode
end
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def original_id(string)
string.base62_decode
end
def find_by_short_id(string)
self.find_by_id(self.original_id(string))
end
end
end
end
<强> Post.rb 强>
class Post < ActiveRecord::Base
include AdditionalMethods::Shortener
...
end
然后
>> @post.id
=> 52
>> @post.short_id
=> "q"
>> Post.original_id("q")
=> 52
>> Post.find_by_short_id("q")
=> #<Post id: 52 ... >