假设我有一个长度约为 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/