为什么这个 bor 和 bnot 表达式在 Powershell 中没有给出预期的结果?
Why doesn't this bor and bnot expression give the expected result in Powershell?
为什么这个 bor b 没有在 powershell 中给出预期的结果?
要找到 ipv6 子网中的最后一个地址,需要执行 "binary or" 和 "binary not" 操作。
我正在阅读的文章 (https://www.codeproject.com/Articles/660429/Subnetting-with-IPv6-Part-1-2) 是这样描述的:
(2001:db8:1234::) | ~(ffff:ffff:ffff::) = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff
哪里|是 "binary or" 和
~ 是 "binary not"
然而,在 powershell 中,我这样尝试:
$mask = 0xffffffff
$someOctet = 0x0000
"{0:x4}" -f ($someOctet -bor -bnot ($mask) )
我得到 0000 而不是 ffff
这是为什么?
本教程正在对整个子网掩码进行 -not
,因此 ff00
反转为 00ff
并且对于更长的 Fs 和 0s 类似;你没有这样做,所以你不会得到相同的结果。
您显示的完全展开的计算是这样做的:
1. (2001:0db8:1234:0000:0000:0000:0000:0000) | ~(ffff:ffff:ffff:0000:0000:0000:0000:0000)
2. (2001:0db8:1234:0000:0000:0000:0000:0000) | (0000:0000:0000:ffff:ffff:ffff:ffff:ffff)
3. = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff
注意在第 1 步到第 2 步中,not
如何反转 Fs 和 0s 的模式,切换子网掩码,并在 位 前缀结束的位置和主机部分开始的 位 。
然后第 3 步 or
仅从左侧取设置位以保持这些数字相同(既不归零也不 ffff'),并且 all从右边开始的设置位(到 ffff 那些,将它们最大化到该前缀内的最大 IP 地址)。
换句话说,这样做是没有意义的"an octet at a time"。这是一个完整的IP地址(或完整的前缀)+完整的子网掩码操作。
教程说的地方:
& (AND), | (OR), ~ (NOT or bit INVERTER): We will use these three bitwise operators in our calculations. I think everybody is familiar -at least from university digital logic courses- and knows how they operate. I will not explain the details here again. You can search for 'bitwise operators' for further information.
如果您对它们的作用不是很熟悉,那么在尝试将它们应用于 IP 子网划分之前,值得多研究一下。因为您基本上是在问为什么 0 or (not 1)
是 0
,而答案是因为这就是布尔逻辑 "or" 和 "not" 的工作方式。
编辑您的评论
[math]::pow(2,128)
比 [decimal]::maxvalue
大很多,所以我认为 Decimal 不行。
我不知道推荐的方法是什么,但我想如果你真的想在 PowerShell 中用 -not
完成这一切,你必须用 [=22= 处理它](例如 [bigint]::Parse('20010db8123400000000000000000000', 'hex')
)。
但更有可能的是,您会做一些更冗长的事情,例如:
# parse the address and mask into IP address objects
# which saves you having to expand the short version to
$ip = [ipaddress]::Parse('fe80::1')
$mask = [ipaddress]::Parse('ffff::')
# Convert them into byte arrays, then convert those into BitArrays
$ipBits = [System.Collections.BitArray]::new($ip.GetAddressBytes())
$maskBits = [System.Collections.BitArray]::new($mask.GetAddressBytes())
# ip OR (NOT mask) calculation using BitArray's own methods
$result = $ipBits.Or($maskBits.Not())
# long-winded way to get the resulting BitArray back to an IP
# via a byte array
$byteTemp = [byte[]]::new(16)
$result.CopyTo($byteTemp, 0)
$maxIP = [ipaddress]::new($byteTemp)
$maxIP.IPAddressToString
# fe80:ffff:ffff:ffff:ffff:ffff:ffff:ffff
为什么这个 bor b 没有在 powershell 中给出预期的结果?
要找到 ipv6 子网中的最后一个地址,需要执行 "binary or" 和 "binary not" 操作。
我正在阅读的文章 (https://www.codeproject.com/Articles/660429/Subnetting-with-IPv6-Part-1-2) 是这样描述的:
(2001:db8:1234::) | ~(ffff:ffff:ffff::) = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff
哪里|是 "binary or" 和
~ 是 "binary not"
然而,在 powershell 中,我这样尝试:
$mask = 0xffffffff
$someOctet = 0x0000
"{0:x4}" -f ($someOctet -bor -bnot ($mask) )
我得到 0000 而不是 ffff
这是为什么?
本教程正在对整个子网掩码进行 -not
,因此 ff00
反转为 00ff
并且对于更长的 Fs 和 0s 类似;你没有这样做,所以你不会得到相同的结果。
您显示的完全展开的计算是这样做的:
1. (2001:0db8:1234:0000:0000:0000:0000:0000) | ~(ffff:ffff:ffff:0000:0000:0000:0000:0000)
2. (2001:0db8:1234:0000:0000:0000:0000:0000) | (0000:0000:0000:ffff:ffff:ffff:ffff:ffff)
3. = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff
注意在第 1 步到第 2 步中,not
如何反转 Fs 和 0s 的模式,切换子网掩码,并在 位 前缀结束的位置和主机部分开始的 位 。
然后第 3 步 or
仅从左侧取设置位以保持这些数字相同(既不归零也不 ffff'),并且 all从右边开始的设置位(到 ffff 那些,将它们最大化到该前缀内的最大 IP 地址)。
换句话说,这样做是没有意义的"an octet at a time"。这是一个完整的IP地址(或完整的前缀)+完整的子网掩码操作。
教程说的地方:
& (AND), | (OR), ~ (NOT or bit INVERTER): We will use these three bitwise operators in our calculations. I think everybody is familiar -at least from university digital logic courses- and knows how they operate. I will not explain the details here again. You can search for 'bitwise operators' for further information.
如果您对它们的作用不是很熟悉,那么在尝试将它们应用于 IP 子网划分之前,值得多研究一下。因为您基本上是在问为什么 0 or (not 1)
是 0
,而答案是因为这就是布尔逻辑 "or" 和 "not" 的工作方式。
编辑您的评论
[math]::pow(2,128)
比 [decimal]::maxvalue
大很多,所以我认为 Decimal 不行。
我不知道推荐的方法是什么,但我想如果你真的想在 PowerShell 中用 -not
完成这一切,你必须用 [=22= 处理它](例如 [bigint]::Parse('20010db8123400000000000000000000', 'hex')
)。
但更有可能的是,您会做一些更冗长的事情,例如:
# parse the address and mask into IP address objects
# which saves you having to expand the short version to
$ip = [ipaddress]::Parse('fe80::1')
$mask = [ipaddress]::Parse('ffff::')
# Convert them into byte arrays, then convert those into BitArrays
$ipBits = [System.Collections.BitArray]::new($ip.GetAddressBytes())
$maskBits = [System.Collections.BitArray]::new($mask.GetAddressBytes())
# ip OR (NOT mask) calculation using BitArray's own methods
$result = $ipBits.Or($maskBits.Not())
# long-winded way to get the resulting BitArray back to an IP
# via a byte array
$byteTemp = [byte[]]::new(16)
$result.CopyTo($byteTemp, 0)
$maxIP = [ipaddress]::new($byteTemp)
$maxIP.IPAddressToString
# fe80:ffff:ffff:ffff:ffff:ffff:ffff:ffff