如何在ruby中解包大于64位的数字?

假设我有一个长约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位,如果平台支持它)的块中执行相同的操作:

 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 

非常感谢https://stackoverflow.com/a/17014450/204070 。 对我来说很棒。 答案可以简化为:

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