我不知道';我不理解这个从base-256转换为十进制的ruby代码
代码的目标很简单:将base-256字节字符串转换为base-10我不知道';我不理解这个从base-256转换为十进制的ruby代码,ruby,Ruby,代码的目标很简单:将base-256字节字符串转换为base-10 def debase256(string) string.reverse.bytes.inject([0, 1]) do |(sum, pow), byte| [pow * byte.ord, pow * 256] end.first end 我试着读它,但我只读了“reverse.bytes” 我无法想象字节在这个过程中是如何移动和变化的 我只需要一个例子来解释这一点。inject执行一个循环,其中“累加变量
def debase256(string)
string.reverse.bytes.inject([0, 1]) do |(sum, pow), byte|
[pow * byte.ord, pow * 256]
end.first
end
我试着读它,但我只读了“reverse.bytes”
我无法想象字节在这个过程中是如何移动和变化的
我只需要一个例子来解释这一点。
inject
执行一个循环,其中“累加变量”(也称为“memo对象”)是一个两元素数组,最初设置为[0,1]
。在每次迭代中,该对象作为[sum,pow]
传递给循环体,以及输入数组中存储在字节中的下一个元素。循环体计算在下一次迭代中使用的更新的备忘录对象。inject
的结果是memo对象的最终值
您可以通过将循环体替换为
[pow * byte.ord, pow * 256].tap do
|new_sum, new_pow|
puts "Working on byte #{byte.inspect}"
puts "old sum and pow : #{sum},#{pow}"
puts "new sum and pow : #{new_sum}, #{new_pow}"
end
inject
执行循环,“累加变量”(也称为“memo对象”)是一个两元素数组,最初设置为[0,1]
。在每次迭代中,该对象作为[sum,pow]
传递给循环体,以及输入数组中存储在字节中的下一个元素。循环体计算在下一次迭代中使用的更新的备忘录对象。inject
的结果是memo对象的最终值
您可以通过将循环体替换为
[pow * byte.ord, pow * 256].tap do
|new_sum, new_pow|
puts "Working on byte #{byte.inspect}"
puts "old sum and pow : #{sum},#{pow}"
puts "new sum and pow : #{new_sum}, #{new_pow}"
end
假设字符串为“AB”(ASCII码为65和66):
string.reverse.bytes
为您提供[66,65]
[66,65]。inject([0,1])
遍历数组[66,65]
,并将结果数组[0,1]
带到每个迭代中。循环需要返回数组的修改版本,并将其传递给下一次迭代
例1:
[66,65].inject([0,1]) do |(sum, pow), byte|
puts "sum: #{sum} pow: #{pow} byte: #{byte}"
[sum, pow] # this gets passed to the next round
end
这将产生:
sum: 0 pow: 1 byte: 66
sum: 0 pow: 1 byte: 65
["byte is 66", "byte is 65"]
使用不同类型的“备注”数组:
因此,inject类似于每一个,但是给定的“memo”对象将从每一轮传递到下一轮
该方法使用memo保存两个值:下一个字节的总和和乘数
将调试输出添加到原始方法:
def debase256(string)
string.reverse.bytes.inject([0, 1]) do |(sum, pow), byte|
puts "sum: #{sum} pow: #{pow} byte: #{byte}"
[pow * byte.ord, pow * 256]
end.first
end
使用debase256(“ABC”)
输出运行此命令:
sum: 0 pow: 1 byte: 67
sum: 67 pow: 256 byte: 66
sum: 16896 pow: 65536 byte: 65
因此,我们看到第一轮的|(sum,pow),byte
的输入是(0,1),67
pow*byte.ord
是1*67=67
pow*256
是1*256=256
因此,第二轮的|(sum,pow),字节
将是:(67256),66
pow*byte.ord
是256*66=16896
pow*256
是256*256=65536
所以最后一轮的|(sum,pow),字节
是:(1689665536),65
:
pow*byte.ord
是65536*65=4259840
pow*256
是65536*256=16777216
因为这是最后一轮,块将返回备忘录,即[425984016777216]
。第一个元素包含所需的结果,而最后一个元素不再需要,因此将调用第一个元素来获取总和。假设字符串为“AB”(其中ASCII代码为65和66):
string.reverse.bytes
为您提供[66,65]
[66,65]。inject([0,1])
遍历数组[66,65]
,并将结果数组[0,1]
带到每个迭代中。循环需要返回数组的修改版本,并将其传递给下一次迭代
例1:
[66,65].inject([0,1]) do |(sum, pow), byte|
puts "sum: #{sum} pow: #{pow} byte: #{byte}"
[sum, pow] # this gets passed to the next round
end
这将产生:
sum: 0 pow: 1 byte: 66
sum: 0 pow: 1 byte: 65
["byte is 66", "byte is 65"]
使用不同类型的“备注”数组:
因此,inject类似于每一个,但是给定的“memo”对象将从每一轮传递到下一轮
该方法使用memo保存两个值:下一个字节的总和和乘数
将调试输出添加到原始方法:
def debase256(string)
string.reverse.bytes.inject([0, 1]) do |(sum, pow), byte|
puts "sum: #{sum} pow: #{pow} byte: #{byte}"
[pow * byte.ord, pow * 256]
end.first
end
使用debase256(“ABC”)
输出运行此命令:
sum: 0 pow: 1 byte: 67
sum: 67 pow: 256 byte: 66
sum: 16896 pow: 65536 byte: 65
因此,我们看到第一轮的|(sum,pow),byte
的输入是(0,1),67
pow*byte.ord
是1*67=67
pow*256
是1*256=256
因此,第二轮的|(sum,pow),字节
将是:(67256),66
pow*byte.ord
是256*66=16896
pow*256
是256*256=65536
所以最后一轮的|(sum,pow),字节
是:(1689665536),65
:
pow*byte.ord
是65536*65=4259840
pow*256
是65536*256=16777216
因为这是最后一轮,块将返回备忘录,即[425984016777216]
。第一个元素包含所需的结果,而最后一个元素不再需要,因此将调用first
来获取总和。代码错误。这不算总数。块中的第一个数组项应该是sum+pow*byte.ord
。另外,将byte.ord
作为Integer#ord
返回本身也没有意义
因此,正确的代码应该是:
def debase256(字符串)
string.reverse.bytes.inject([0,1])do |(sum,pow),byte|
[总和+功率*字节,功率*256]
完
结束
但这段代码有点难理解。也许以下代码(没有方法声明)可以帮助您更好地理解它:
string.reverse.bytes.map.with_index do| byte,i|
字节*256**i
完
让我们看一个字符串为“Test”的示例:
string=“测试”
首先,我们将其逆转:
string.reverse#=>“tseT”
然后我们得到字节: