压缩Ruby / Rails中的hex字符串
我正在使用MongoDB作为我正在构建的Rails应用程序的后端。 默认情况下,Mongo为其记录生成24个字符的hexID,以便更轻松地进行分片,因此我的URL看起来像:
example.com/companies/4b3fc1400de0690bf2000001/employees/4b3ea6e30de0691552000001
这不是很漂亮。 我想坚持使用Rails url约定,但也要将这些ID保留在数据库中。 我认为一个愉快的折衷方案是使用更多字符将这些hex id压缩为更短的集合,因此它们看起来像:
example.com/companies/3ewqkvr5nj/employees/9srbsjlb2r
然后在我的控制器中,我将反转压缩,获取原始的hexID并使用它来查找记录。
我的问题是,来回转换这些ID的最佳方法是什么? 我当然希望它们尽可能短,但也是安全且易于转换的。
谢谢!
您可以在高于16
的基数中表示hexID,以使其字符串表示更短。 Ruby内置支持使用2
到36
。
b36 = '4b3fc1400de0690bf2000001'.hex.to_s(36) # => "29a6dblglcujcoeboqp"
要将其转换回24个字符的字符串,您可以执行以下操作:
'%024x' % b36.to_i(36) # => "4b3fc1400de0690bf2000001"
为了实现更好的“压缩”,您可以表示基数高于36
的id。 有一些Ruby库可以帮助你。 all-your-base
gem就是这样一个库。
我建议使用base 62
表示,因为它只使用0-9
, az
和AZ
字符,这意味着默认情况下它是URL安全的。
即使使用base 62表示,您最终仍会使用仍然笨拙的16个字符ID:
'4b3fc1400de0690bf2000001'.hex.to_base_62 # => "UHpdfMzq7jKLcvyr"
Sidestepping Rails惯例有点,另一个折衷方案是使用“URL id”作为对象的created_at
日期的基数32表示。
aCompany.created_at # => Sat Aug 13 20:05:35 -0500 2011 aCompany.created_at.to_i.to_s(32) # => "174e7qv"
通过这种方式,您可以获得超短ID(7个字符),而无需跟踪特殊用途属性(在MongoMapper中,只需添加timestamps!
在模型中获取自动created_at
和updated_at
属性)。
您可以使用base64缩短它。 确保使用’ – ‘和’_’代替’+’和’/’。 你也可以砍掉padding =。
用于将hex值转换为基数64的代码
def MD5hex2base64(str) h1=[].clear # split the 32 byte hex into a 16 byte array 16.times{ h1.push(str.slice!(0,2).hex) } # pack (C* = unsigned char), (m = base64 encoded output) [h1.pack("C*")].pack("m") end