压缩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内置支持使用236

 b36 = '4b3fc1400de0690bf2000001'.hex.to_s(36) # => "29a6dblglcujcoeboqp" 

要将其转换回24个字符的字符串,您可以执行以下操作:

 '%024x' % b36.to_i(36) # => "4b3fc1400de0690bf2000001" 

为了实现更好的“压缩”,您可以表示基数高于36的id。 有一些Ruby库可以帮助你。 all-your-basegem就是这样一个库。

我建议使用base 62表示,因为它只使用0-9azAZ字符,这意味着默认情况下它是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_atupdated_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