ruby base64 通过以 2 位字符开头来编码 128 位数字,以防止在末尾填充
ruby base64 encode 128 bit number by starting with a 2 bit character to prevent padding at the end
这个问题是我之前在此处提出的问题的后续问题:
但我会尝试将其表述为一个单独且具体的问题。
我确实有一个 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 库将其输入作为字节,因此您需要让输入数据能被 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 位,你可以用一些 pack/unpack:
[x.unpack("B*")[0][4...132]].pack("B*")
这个问题是我之前在此处提出的问题的后续问题:
我确实有一个 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 库将其输入作为字节,因此您需要让输入数据能被 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 位,你可以用一些 pack/unpack:
[x.unpack("B*")[0][4...132]].pack("B*")