我有一个我知道可以表示为32位无符号整数的数字:

num = 3735928559 # 0xDEADBEEF

我如何(相对容易地)将其转换为Ruby中该原始数字的表示形式?

num = 3735928559 # 0xDEADBEEF
num.byte_swap # .byte_swap as stand-in for the process I'm looking for
num = num.byte_swap # now equal to 0xEFBEADDE, or 4,022,250,974

这是为了稍后的位移位和位掩码.

推荐答案

有几种 Select .

您可以通过to_s将其转换为十六进制字符串,使用scanreversejoin一起提取字节,然后通过to_i将结果转换回整数:

num = num.to_s(16)   #=> "deadbeef"
         .scan(/../) #=> ["de", "ad", "be", "ef"]
         .reverse    #=> ["ef", "be", "ad", "de"]
         .join       #=> "efbeadde"
         .to_i(16)   #=> 4022250974

或者使用正则表达式和sub进行反转:

num = num.to_s(16)                            #=> "deadbeef"
         .sub(/(..)(..)(..)(..)/, '\4\3\2\1') #=> "efbeadde"
         .to_i(16)                            #=> 4022250974

或者,您可以使用掩码(&)和位移位(<</>>)将每个字节移动到其新位置:(通过|组合)

num = (num & 0x000000FF) << 24 |
      (num & 0x0000FF00) << 8  |
      (num & 0x00FF0000) >> 8  |
      (num & 0xFF000000) >> 24

或者,正如Rajagopalan in the comments所建议的,您可以利用Ruby的packing and unpacking方法:

num = [num].pack('L<').unpack1('L>')

L指定32位无符号整数,</>指定小端和大端.pack('L<')将该数值转换为二进制4字节字符串"\xDE\xAD\xBE\xEF",并且unpack1('L>')将该字符串数据转换回具有相反字节顺序的数字.

Ruby相关问答推荐

Ruby Case语句和固定,不适用于attr_reader

CarrierWave Multi-uploader重命名现有文件

Jekyll 默认安装没有 _layouts 目录

Ruby $:.unshift File.dirname(__FILE__)

当没有传入块时,是否有更好的方法来防止屈服?

判断Ruby中的目录是否为空

什么是 Sinatra/Rack 的非常简单的身份验证方案

Ruby 在与源相同的目录中加载配置(yaml)文件

是否有等效于 `Array::sample` 的哈希值?

Vagrant - 如何拥有特定于主机平台的配置步骤

Broken pipe (Errno::EPIPE)

在 Selenium WebDriver 中按 Ctrl + A

Ruby 数组中的奇数(或偶数)条目

Ruby 中的超级关键字

哪个键/值存储最有前途/最稳定?

工厂女孩 - 目的是什么?

Ruby 删除目录

为什么在 ruby​​ 中动态创建大量符号不是一个好主意(对于 2.2 之前的版本)?

如何使用#{variable}在Ruby中格式化带有浮点数的字符串?

Ruby:从 Ruby 中的变量创建哈希键和值