Учебное пособие выполняет -not
всей маски подсети, поэтому ff00
инвертируется в 00ff
и аналогично для более длинных F и 0; вы этого не делаете, поэтому вы не получите тех же результатов.
Полностью расширенный расчет, который вы показываете, делает это:
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
инвертирует шаблон F и 0, переключает маску подсети и переключает ее между битом, где заканчивается префикс, и бит, где начинается основная часть.
Затем на шаге 3 or
берутся только установленные биты слева, чтобы эти числа оставались одинаковыми (ни нулевые, ни ffff'd), и все установленные биты справа (чтобы сбросить их, максимизируя их на максимальный IP-адрес в пределах этого префикса).
Другими словами, нет смысла делать это «по октету за раз». Это полный IP-адрес (или весь префикс) + вся операция по маске подсети.
Где в учебнике сказано:
& (И), | (ИЛИ), ~ (НЕ или битовый ИНВЕРТОР): Мы будем использовать эти три побитовых оператора в наших вычислениях. Я думаю, что все знакомы — по крайней мере, из университетских курсов цифровой логики — и знают, как они работают. Я не буду объяснять подробности здесь снова. Вы можете выполнить поиск «битовых операторов» для получения дополнительной информации.
Если вы не очень хорошо знакомы с тем, что они делают, стоит изучить это подробнее, прежде чем пытаться применять их к IP-подсетям. Потому что вы в основном спрашиваете, почему 0 or (not 1)
это 0
, и ответ таков, потому что так работает логическая логика «или» и «не».
Изменить для вашего комментария
[math]::pow(2,128)
намного больше, чем [decimal]::maxvalue
, поэтому я не думаю, что Decimal подойдет.
Я не знаю, какой рекомендуемый способ сделать это, но я полагаю, что если вы действительно хотите сделать все это в PowerShell с помощью -not
, вам придется обрабатывать это с помощью [bigint]
(например, [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
person
TessellatingHeckler
schedule
26.04.2018
ffff
?-bnot 0xffffffff
это0
, почему0x0000 -bor 0
должно быть не0
? Кстати,ffff:ffff:ffff::
— это краткая формаffff:ffff:ffff:0000:0000:0000:0000:0000
. - person user4003407   schedule 26.04.2018