如何在Ruby中将诸如00:16:3e:15:d3:a9
这样的mac地址转换为IPv6链接本地地址(如经过修改的EUI-64,例如fe80::216:3eff:fe15:d3a9
)?
到目前为止,我有以下步骤:
mac = "00:16:3e:15:d3:a9"
mac.delete!(':') # Delete colons
mac.insert(6, 'fffe') # Insert ff:ee in the middle
mac = mac.scan(/.{4}/) # Split into octets of 4
next step将翻转我遇到的第一个八位位组的第六位。
答案 0 :(得分:2)
这是您的主要问题:Ruby是一种面向对象的语言。您可以通过操作丰富的结构化对象来创建程序,更准确地说是通过告诉丰富的结构化对象进行操作来创建程序。
但是,您正在操纵String
。现在,String
当然也是Ruby中的对象,但是它们是表示 text 的对象,而不是表示 IP地址或EUI的对象。
您至少应将其作为IP地址或EUI而不是文本,而应将其视为丰富的,结构化的IP地址对象或EUI对象。
Ruby实际上是a library for manipulating IP addresses的一部分,它是standard library的一部分。
以下是将这些地址视为数字和/或对象的示例:
require 'ipaddr'
eui48 = '00-16-3E-15-D3-A9'
# eliminate all delimiters, note that only ':' is not enough; the standard is '-', but '.' is also sometimes used
eui48 = eui48.gsub(/[^0-9a-zA-Z]/, '')
# parse the EUI-48 as a number
eui48 = eui48.to_i(16)
# split the EUI-48 into the OUI and the manufacturer-assigned parts
oui, assigned = eui48.divmod(1 << 24)
# append 16 zero bits to the OUI
left = oui << 16
# add the standard bit sequence
left += 0xfffe
# append 24 zero bits
left <<= 24
# now we have an EUI-64
eui64 = left + assigned
# flip bit index 57 to create a modified EUI-64
modified_eui64 = eui64 ^ 1 << 57
# the prefix for link-local IPv6 addresses is fe80::/10
prefix = IPAddr.new('fe80::/10')
# the suffix is based on our modified EUI-64
suffix = IPAddr.new(modified_eui64, Socket::AF_INET6)
# the final result is the bitwise logical OR of the prefix and suffix
link_local_ipv6 = prefix | suffix
# the IP address library knows how to correctly format an address according to RFC 5952 Section 4
link_local_ipv6.to_s
#=> 'fe80::216:3eff:fe15:d3a9'