ruby - 如何在 Ruby 中反转数字的 "byte order"

标签 ruby endianness

我知道一个数字可以表示为 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

这是为了以后的位移位和位掩码。

最佳答案

有多种选择。

您可以通过 to_s 将其转换为十六进制字符串,使用 scan 提取字节, reverse 他们, join 将它们组合在一起,并通过 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 中反转数字的 "byte order",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76113203/

相关文章:

c# - IPAddress.HostToNetworkOrder() 在 WinRT 中等效吗?

c - 大端和小端机器的结构填充

ruby - 无法在 watir 中使用 cmd 提示符打开 Firefox 浏览器

ruby - 按百分比选择数组中的项目

ruby - 删除标签但保留文本

c++ - 将 uint16_t 解释为 int16_t

ruby - `Dir.entries` 中的排序顺序

ruby capybara - 在运行时获取 xpath

arm - 如何在 ARM/ACLE 中交换向量中单个单词的字节顺序

c++ - 将 C++ 中的位交换为 double