В учебнике выполняется -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
инвертирует комбинацию Fs и 0s, переключаямаску подсети и ее переключение между бит , где заканчивается префикс, и бит , где начинается хост-часть.
Затем выполняется шаг 3 or
только установленные биты слева сохраняют эти числа одинаковыми (ни ноль, ни ffff'd), и все установленные биты справа (для ffff их, максимизируя их до максимального IP-адреса)внутри этого префикса).
Другими словами, нет смысла делать этот «октет за раз».Это полный IP-адрес (или весь префикс) + целая операция с маской подсети.
Там, где в учебнике говорится:
& (AND), |(ИЛИ), ~ (НЕ или битовый ИНВЕРТОР): Мы будем использовать эти три побитовых оператора в наших вычислениях.Я думаю, что все знакомы - по крайней мере, с университетских курсов по цифровой логике - и знают, как они работают.Я не буду объяснять детали здесь снова.Вы можете искать «побитовые операторы» для получения дополнительной информации.
Если вы не очень хорошо знакомы с тем, что они делают, стоит изучить их подробнее, прежде чем пытаться применить их к IP-подсетям.Потому что вы в основном спрашиваете, почему 0 or (not 1)
равно 0
, а ответ таков, как работают булевы логики "или" и "не".
Редактируйте свой комментарий
[math]::pow(2,128)
намного больше, чем [decimal]::maxvalue
, поэтому я не думаю, что Десятичная будет делать.
Я не знаю, какой рекомендуемый способ это сделать, но я думаю, что если вы действительно хотите сделать все это в 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