如何在Ruby中将GUID转换为字节数组?

时间:2019-02-20 14:38:46

标签: ruby-on-rails ruby

为了节省数据流量,我们希望将GUID发送为字节数组而不是字符串(使用Google协议缓冲区)。

如何将Ruby中的GUID的字符串表示形式转换为字节数组:

示例:

$regex = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)$/';

在.NET中,这似乎是本机实现的: http://msdn.microsoft.com/en-us/library/system.guid.tobytearray%28v=vs.110%29.aspx

1 个答案:

答案 0 :(得分:2)

您的示例GUID是Microsoft特定的格式。来自Wikipedia

  

其他系统(尤其是Microsoft在其COM / OLE库中编排的UUID)使用混合字节序格式,其中UUID的前三个组件是小字节序,后两个是大字节序。

因此,为了获得该结果,我们必须稍微移动一下位。具体来说,我们必须更改前三个组件的流行程度。让我们首先将GUID字符串分开:

guid = '35918bc9-196d-40ea-9779-889d79b753f0'
parts = guid.split('-')
#=> ["35918bc9", "196d", "40ea", "9779", "889d79b753f0"]

我们可以通过以下方式将这些十六进制字符串转换为二进制字符串:

mixed_endian = parts.pack('H* H* H* H* H*')
#=> "5\x91\x8B\xC9\x19m@\xEA\x97y\x88\x9Dy\xB7S\xF0"

接下来让我们交换前三个部分:

big_endian = mixed_endian.unpack('L< S< S< A*').pack('L> S> S> A*')
#=> "\xC9\x8B\x915m\x19\xEA@\x97y\x88\x9Dy\xB7S\xF0"
  • L表示32位无符号整数(第一部分)
  • S表示16位无符号整数(第二和第三部分)
  • <>分别表示little-endian和big-endian
  • A*将其余字节视为任意二进制字符串(我们无需转换这些字符串)

如果您希望使用字节数组而不是二进制字符串,则只需使用:

big_endian.bytes
#=> [201, 139, 145, 53, 109, 25, 234, 64, 151, 121, 136, 157, 121, 183, 83, 240]

PS:如果您的实际GUID不是Microsoft特定的,则可以跳过交换部分。