为什么这个 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