ruby base64 通过以 2 位字符开头来编码 128 位数字,以防止末尾填充

标签 ruby uuid guid ifc

这个问题是我上一个问题的后续问题:How can I convert a UUID to a string using a custom character set in Ruby? 但我会尝试将其表述为一个单独且具体的问题。

我确实有一个 Ruby 128 位 UUID 作为十六进制值:

SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"

如果我正确获得了 IFC 规范( http://www.buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ifcutilityresource/lexical/ifcgloballyuniqueid.htm ),我想对其进行 Base64 编码,但我希望输出以 2 位字符(4 个选项)而不是 6 个字符开头,而不是在末尾进行填充位(64 个选项需要)。

这样我想我最终可以得到一个 22 个字符的字符串(1 个 2 位,21 个 6 位,总共 128 位)。

是否可以通过这种方式调整 Ruby base64?

最佳答案

简短回答:不。从技术上讲,这不是标准的 Base64,因此 Ruby 的标准库不会处理它。

Ruby 的 Base64 lib 将其输入视为字节,因此您需要让输入数据能被 8 整除。但是您需要在 UUID 前面有 4 个零位,所以这是 4+128=132,所以下一个最接近的倍数8 个是 136,即 17 个字节。您可以在最后丢弃额外的随机性:

x = SecureRandom.gen_random 17   # get a little extra randomness
x[0] = (x[0].ord & 0x0f).chr     # 0 out the first four bits
Base64.strict_encode64(x)[0...22] # discard extra randomness

这种方法的一个缺点是您的 128 位 UUID 在 x 内部奇怪地对齐,并且很难单独看到。如果你想取出 128 位,你可以通过一些打包/解包来实现:

[x.unpack("B*")[0][4...132]].pack("B*")

关于ruby base64 通过以 2 位字符开头来编码 128 位数字,以防止末尾填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47839720/

相关文章:

ruby-on-rails - 为什么 "render ' new'“改变我的 URL?(Ruby On Rails)

java - RandomStringUtils.randomAlphanumeric(30) 是有效的 GUID 策略吗?

asp.net - 一个小但恼人的问题——为什么 ASP.Net 将 SQL Server Guids 设置为小写?

ruby - 调试ruby算法

Ruby File.read 与 File.gets

java - 在jaxb中转换xs :string to java. util.UUID

android - 在 Android 2.3.x 上使用 SDP 获取具有特定 UUID 的设备

sql - 如何在 SQL Server 中存储 token

java - Java Web 应用程序中的唯一序列号

ruby - 从原始范围之外的 ruby block 返回