Почему это выражение бора и банта не дает ожидаемого результата в Powershell? - PullRequest
0 голосов
/ 26 апреля 2018

почему этот бор не дает ожидаемого результата в powershell?

Чтобы найти последний адрес в подсети ipv6, нужно выполнить операцию "двоичный код" или "двоичный код".

В статье, которую я читаю (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

Где | - это двоичный код или *, а 1010 * ~ - это двоичный файл, не являющийся"


В PowerShell, однако, я пытаюсь это сделать так:

$mask = 0xffffffff
$someOctet = 0x0000
"{0:x4}" -f ($someOctet -bor -bnot ($mask) )

и я получаю 0000 вместо ffff

Почему это так?

1 Ответ

0 голосов
/ 26 апреля 2018

В учебнике выполняется -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
...