为什么';这个bor和bnot表达式在Powershell中不给出预期的结果吗?

为什么';这个bor和bnot表达式在Powershell中不给出预期的结果吗?,powershell,binary-operators,Powershell,Binary Operators,为什么这个bor不能在powershell中给出预期的结果 要查找ipv6子网中的最后一个地址,需要执行“二进制或”和“二进制非”操作 我正在阅读的文章()描述如下: (2001:db8:1234::) | ~(ffff:ffff:ffff::) = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff 其中|是“二进制或”且 ~是“二进制非” 但是,在powershell中,我会像这样尝试: $mask = 0xffffffff $someOctet = 0x000

为什么这个bor不能在powershell中给出预期的结果

要查找ipv6子网中的最后一个地址,需要执行“二进制或”和“二进制非”操作

我正在阅读的文章()描述如下:

(2001:db8:1234::) | ~(ffff:ffff:ffff::) = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff
其中|是“二进制或”且
~是“二进制非”


但是,在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
只取左侧的设置位,以保持这些数字相同(既不为零也不为ffff'd),并取右侧的所有设置位(为了ffff这些设置位,将它们最大化为该前缀内的最大IP地址)

换句话说,这样做“一次八个字节”是没有意义的。这是整个IP地址(或整个前缀)+整个子网掩码操作

教程中说:

&(和),|(或),~(NOT或位反相器):我们将在计算中使用这三个位运算符。我认为每个人都很熟悉——至少在大学数字逻辑课程中是如此——并且知道它们是如何运作的。我不会在这里再解释细节。您可以搜索“按位运算符”以获取更多信息

如果您对它们的工作不是很熟悉,那么在尝试将它们应用于IP子网之前,应该进一步研究它们。因为你基本上是在问为什么
0或(不是1)
0
,答案是因为这就是布尔逻辑“或”和“非”的工作原理


编辑您的评论

[math]::pow(2128)
[decimal]::maxvalue
大得多,所以我认为decimal不行

我不知道推荐的方法是什么,但我想如果您真的想在PowerShell中使用
-而不是
,那么您必须使用
[bigint]
处理它(例如
[bigint]::Parse('20010db8123400000000000000000',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

本教程将对整个子网掩码执行
-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
只取左侧的设置位,以保持这些数字相同(既不为零也不为ffff'd),并取右侧的所有设置位(为了ffff这些设置位,将它们最大化为该前缀内的最大IP地址)

换句话说,这样做“一次八个字节”是没有意义的。这是整个IP地址(或整个前缀)+整个子网掩码操作

教程中说:

&(和),|(或),~(NOT或位反相器):我们将在计算中使用这三个位运算符。我认为每个人都很熟悉——至少在大学数字逻辑课程中是如此——并且知道它们是如何运作的。我不会在这里再解释细节。您可以搜索“按位运算符”以获取更多信息

如果您对它们的工作不是很熟悉,那么在尝试将它们应用于IP子网之前,应该进一步研究它们。因为你基本上是在问为什么
0或(不是1)
0
,答案是因为这就是布尔逻辑“或”和“非”的工作原理


编辑您的评论

[math]::pow(2128)
[decimal]::maxvalue
大得多,所以我认为decimal不行

我不知道推荐的方法是什么,但我想如果您真的想在PowerShell中使用
-而不是
,那么您必须使用
[bigint]
处理它(例如
[bigint]::Parse('20010db8123400000000000000000',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

您为什么期望
ffff
-bnot 0xFFFFFF
0
,为什么
0x0000-bor 0
不应该是
0
?顺便说一句,
ffff:ffff:ffff::
ffff:ffff:ffff:0000:0000:0000
的缩写形式。由于教程的原因……可能这是一个糟糕的教程。我试图一次做一个八位组。你为什么期待
ffff
-bnot 0xFFFFFF
0
,为什么
0x0000-bor 0
不应该是
0
?顺便说一句,
ffff:ffff:ffff::
ffff:ffff:ffff:0000:0000:0000
的缩写形式。由于教程的原因…可能这是一个糟糕的教程。我试图一次做一个八位字节。因此,如果ipv6地址中有128位,您必须将其和子网掩码以
[十进制]的形式存储在PowerShell中
因为
[decimal]
数据类型是128位……这是一个很大的变量!如果像这样存储地址:
[decimal]$ipv6addr=0x20010db812340
我是否会在该地址之后的右边全部为零?因为如果我键入
[decimal]$ipv6addr=0x20010db81234000000000000
我所做的就是被
pwsh
用parentcontainersorrecordexception对我大喊大叫,我已经编辑了我的答案来回复,因为我无法在评论中表达更多的内容。(现在我明白你为什么要用八重奏