如何在 Ruby 中将十进制值数组转换为 MAC 地址?
Posted
技术标签:
【中文标题】如何在 Ruby 中将十进制值数组转换为 MAC 地址?【英文标题】:How do I convert an array of decimal values to a MAC address in Ruby? 【发布时间】:2015-12-10 18:34:50 【问题描述】:我有一个字符串数组,每个项目都是一个以 10 为底的十进制值,需要转换为以 16 为底的等效值:
输入:
a = ["23", "137", "44", "30", "38", "2"]
输出:
#=> ["17", "89", "2c", "1e", "26", "02"]
理想情况下,我需要数组真正代表的内容,即 48 字节的 MAC 地址:
#=> "17892c1e2602" or "17:89:2c:1e:26:02"
我尝试了 pack
和 unpack
并失败了:
a.map |i| i.to_s(16)
结果为@987654327@。
任何有关转换的帮助将不胜感激。
【问题讨论】:
【参考方案1】:您可以将Kernel#sprintf 格式与x
字段类型一起使用:
a = ["23", "137", "44", "30", "38", "2"]
"%02x"*a.size % a
#=> "17892c1e2602"
步骤:
"%02x"*a.size % a
#=> "%02x"*6 % ["23", "137", "44", "30", "38", "2"]
# "%02x%02x%02x%02x%02x%02x" % ["23", "137", "44", "30", "38", "2"]
#=> "17892c1e2602"
在"%02x"
:
sprintf
格式如下
字段类型x
表示“将参数[整数或字符串]转换为十六进制数”
2
是字段宽度
0
表示用零而不是空格填充
插入冒号:
(["%02x"]*a.size).join(':') % a
#=> "17:89:2c:1e:26:02"
【讨论】:
谢谢,@Jesse。我注意到了这一点,而且我可以简化。 这样做:"#'%02x:'*["232", "137", "44", "30", "37", "18"].size".gsub(/:$/,"") % ["232", "137", "44", "30", "37", "18"].map(&:to_i)
是的,@Tyler,但美在旁观者眼中。
@CarySwoveland,不是美观的问题,而是处理速度的问题。在我对这两种工作解决方案的测试中,.map()
解决方案在 1000 次迭代中的运行速度提高了 22%,我需要每 5 分钟处理超过 13k 次,因此任何时间剃须都是理想的
@Tyler,你是对的,gsub!
会更快。另一种选择是将其作为一个单独的步骤(s[-1] = '')
。它仍然很丑,但并不比我处理那个讨厌的尾随分号的方式更丑。丑陋的是必须进行清理,Stefan/mudasobwa 的建议避免了这一点。谢谢你的cmets。 ——【参考方案2】:
a = ["23", "137", "44", "30", "38", "2"]
a.map(&:to_i).map |i| i.to_s(16).rjust(2, '0') .join ':'
#=> "17:89:2c:1e:26:02"
UPD 正如 Cary 在 cmets 中所建议的,在随后的两个 map
s 中不需要:
a.map |s| s.to_i.to_s(16).rjust(2, '0') .join ':'
#=> "17:89:2c:1e:26:02"
【讨论】:
这可以完成工作:["232", "137", "44", "30", "37", "18"].map(&:to_i).map |i| i.to_s(16).rjust(2,'0') .join ':'
并且在测试中是最快的
@CarySwoveland 确实,谢谢,答案已更新。
抱歉,我不应该删除我的评论,因为它提供了上下文。它是,“好一个,mudsie。连续两张地图很少是一件好事。考虑将它们组合起来。”
@mudasobwa 我已经将数组提取到一个变量中,并用更简洁的 ...
替换了do ... end
- 希望你不介意:-)
@Stefan 绝对是,随意更改任何内容,包括我的昵称 :) 顺便说一句,当我介意时,我拒绝编辑。以上是关于如何在 Ruby 中将十进制值数组转换为 MAC 地址?的主要内容,如果未能解决你的问题,请参考以下文章