【问题标题】:Compressing a hex string in Ruby/Rails在 Ruby/Rails 中压缩十六进制字符串
【发布时间】:2010-12-31 21:04:18
【问题描述】:

我正在使用 MongoDB 作为我正在构建的 Rails 应用程序的后端。默认情况下,Mongo 会为其记录生成 24 个字符的十六进制 id,以使分片更容易,所以我的 URL 最终看起来像:

example.com/companies/4b3fc1400de0690bf2000001/employees/4b3ea6e30de0691552000001

这不是很漂亮。我想坚持 Rails url 约定,但也将这些 id 保留在数据库中。我认为一个愉快的折衷方案是将这些十六进制 id 压缩为使用更多字符的较短集合,因此它们看起来像:

example.com/companies/3ewqkvr5nj/employees/9srbsjlb2r

然后在我的控制器中,我将反向压缩,获取原始的十六进制 id 并使用它来查找记录。

我的问题是,来回转换这些 id 的最佳方法是什么?我当然希望它们尽可能短,而且网址安全且易于转换。

谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby mongodb


    【解决方案1】:

    您可以在高于16 的基数中表示十六进制 id,以使其字符串表示更短。 Ruby 内置支持从 236 的基础。

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

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

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

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

    我推荐基本的62 表示,因为它只使用0-9a-zA-Z 字符,这意味着默认情况下它是 URL 安全的。

    【讨论】:

      【解决方案2】:

      即使使用 base 62 表示,您最终还是会得到仍然笨拙的 16 个字符的 id:

      '4b3fc1400de0690bf2000001'.hex.to_base_62  
      # => "UHpdfMzq7jKLcvyr"
      

      稍微回避一下 Rails 约定,另一个折衷方案是使用对象的 created_at 日期的 base 32 表示作为“URL id”。

      aCompany.created_at
      # => Sat Aug 13 20:05:35 -0500 2011
      aCompany.created_at.to_i.to_s(32)
      # => "174e7qv"
      

      通过这种方式,您无需跟踪特殊用途的属性(在 MongoMapper 中,只需在模型中添加 timestamps! 即可自动获得 created_atupdated_at,即可获得超短 ID(7 个字符)属性)。

      【讨论】:

        【解决方案3】:

        您可以使用 base64 使其更短。确保您使用的是“-”和“_”而不是“+”和“/”。你也可以砍掉填充=。

        将十六进制值转换为基数 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
        

        【讨论】:

        • 我该怎么做?我尝试在字符串 id 上使用 Base64.encode64,但这只会使它们更长。
        • 这个 sn-p 展示了如何做到这一点rubyforge.org/snippet/detail.php?type=snippet&id=33
        • Base64.encode64 使 id 更长,因为您将它们用作字符串而不是二进制数据。
        猜你喜欢
        • 2012-07-31
        • 2020-06-01
        • 2017-03-21
        • 1970-01-01
        • 2016-11-01
        • 2020-11-11
        • 2021-12-26
        • 2010-10-04
        • 2012-01-11
        相关资源
        最近更新 更多