ruby - 如何在 ruby​​ 中解压大于 64 位的数字?

标签 ruby unpack

假设我有一个长度约为 1000 字节的任意字符串。 (我正在研究加密。)如何将其解压到 BigNum 中?我了解如何将其打包成 8 位数字或 32 位数字。

s='I am a grumpy potato'
s.unpack('C*')
[73, 32, 97, 109, 32, 97, 32, 103, 114, 117, 109, 112, 121, 32, 112, 111, 116, 97, 116, 111]
s.upack('L*')
=> [1835081801, 1730175264, 1886221682, 1869619321, 1869898100]

或者,是否有直接的方法将 8 位数字组合成一个 BigNum?我可能会解包成一个 8 位数字的数组,然后将数组的每个元素乘以 8 的后续幂。但这似乎太复杂了,不是正确的方法。

编辑:将 BigNum 变回字符串的首选方法是什么?我不是说 to_s,我是说采用相同的字节模式并将其解释为字符串?

最佳答案

我认为您对如何处理它的预感是正确的。 Unpack 不处理 Bignums;它们通常相当棘手,特别是因为它们不适合标准的 64 位 int。

您可以通过以下方式手动“解压”它:

str.unpack("C*").reverse.each_with_index.inject(0) do |sum, (byte, index)|
  sum + byte * (256 ** index)
end

也就是说,反转字节列表(如果在大端系统上),迭代每个字节,并将其值乘以 256^position。一旦值变得足够大,Ruby 的 BigNum 就会启动,您可以毫不费力地将字节字符串转换为非常大的数字。

您也可以在 32 位(或 64 位,如果平台支持的话)整数 block 中执行相同的操作:

INT32_MAX = 256 ** [1].pack("L*").size
INT64_MAX = 256 ** [1].pack("Q*").size

str.unpack("L*").reverse.each_with_index.inject(0) do |sum, (byte, index)|
  sum + byte * (INT32_MAX ** index)
end

str.unpack("Q*").reverse.each_with_index.inject(0) do |sum, (byte, index)|
  sum + byte * (INT64_MAX ** index)
end

关于ruby - 如何在 ruby​​ 中解压大于 64 位的数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17014268/

相关文章:

python - 简单读取 fortran 二进制数据在 python 中并不那么简单

python - 使用 struct.pack 和 struct.unpack 的问题

python - 在 Python 中解压格式字符

buffer - 如何在 Golang 的字节缓冲区中解压缩各种形式的整数?

php - 在 Ruby 中解密 PHP MCRYPT_RIJNDAEL_256

带有 attr_accessor 的类上的 Ruby instance_eval

javascript - 你能在javascript中创建一个check_box_tag吗

perl - 我可以使用 Perl 的 unpack 将字符串分解为 var 吗?

ruby - 检测字符串是文件还是目录的简单方法

ruby - 'downcase' 的未定义方法。 (WATIR/Ruby 相关。webdriver-user-agent)