rep*_*ept 2 ruby ruby-on-rails
为了节省数据流量,我们希望将 GUID 作为字节数组而不是字符串发送(使用 Google Protocol Buffers)。
如何将 Ruby 中 GUID 的字符串表示形式转换为字节数组:
例子:
Guid: 35918bc9-196d-40ea-9779-889d79b753f0
=> Result: C9 8B 91 35 6D 19 EA 40 97 79 88 9D 79 B7 53 F0
Run Code Online (Sandbox Code Playgroud)
在.NET中,这似乎是本机实现的: http://msdn.microsoft.com/en-us/library/system.guid.tobytearray%28v=vs.110%29.aspx
您的示例 GUID 采用 Microsoft 特定格式。来自维基百科:
其他系统,特别是 Microsoft 在其 COM/OLE 库中对 UUID 进行编组,使用混合字节序格式,其中 UUID 的前三个组成部分是小字节序,后两个是大字节序。
因此,为了获得该结果,我们必须稍微移动这些位。具体来说,我们必须更改前三个组件的字节顺序。让我们首先将 GUID 字符串分开:
guid = '35918bc9-196d-40ea-9779-889d79b753f0'
parts = guid.split('-')
#=> ["35918bc9", "196d", "40ea", "9779", "889d79b753f0"]
Run Code Online (Sandbox Code Playgroud)
我们可以通过以下方式将这些十六进制字符串转换为二进制:
mixed_endian = parts.pack('H* H* H* H* H*')
#=> "5\x91\x8B\xC9\x19m@\xEA\x97y\x88\x9Dy\xB7S\xF0"
Run Code Online (Sandbox Code Playgroud)
接下来让我们交换前三部分:
big_endian = mixed_endian.unpack('L< S< S< A*').pack('L> S> S> A*')
#=> "\xC9\x8B\x915m\x19\xEA@\x97y\x88\x9Dy\xB7S\xF0"
Run Code Online (Sandbox Code Playgroud)
L表示 32 位无符号整数(第一个组成部分)S表示 16 位无符号整数(第二个和第三个分量)<和>分别表示小端和大端A*将剩余字节视为任意二进制字符串(我们不必转换它们)如果您更喜欢字节数组而不是二进制字符串,则只需使用:
big_endian.bytes
#=> [201, 139, 145, 53, 109, 25, 234, 64, 151, 121, 136, 157, 121, 183, 83, 240]
Run Code Online (Sandbox Code Playgroud)
PS:如果您的实际 GUID 不是 Microsoft 特定的,您可以跳过交换部分。
| 归档时间: |
|
| 查看次数: |
640 次 |
| 最近记录: |