构建 IP 地址列表
Building a list of IP addresses
我正在尝试根据用户的输入构建一组可能的 IP 地址。即 IP 地址和 CIDR 号码。我的最终目标是将此列表与单独的地址列表进行比较,找出缺少的地址。
例子
用户输入:192.168.1.0 /24
我想为 /24 网络的所有可能值构建一个数组(即 IP 地址可以是 192.168.1.0 - 192.168.1.255 之间的任何位置)
为了让它工作,我想我必须将 IP 地址转换为二进制,然后找到将成为网络主机部分的位,我已在此处完成:
function ConvertToBinary{
param($ipAddress)
[string]$binaryIP = -join ($ipAddress.Split('.') | ForEach-Object {[System.Convert]::ToString($_,2).PadLeft(8,'0')})
return $binaryIP
}
function FindHost{
param(
[string]$binaryIPAddress,
[int32]$CIDR
)
$hostBits = 32-$CIDR
[string]$myHost = $binaryIPAddress.Substring($binaryIPAddress.Length-$hostBits)
return $myHost
}
$myip = ConvertToBinary "192.168.3.1"
$myHost = FindHost $myip 8
我对如何进行有点困惑,所以如果有人能帮助我或指出正确的方向,我将不胜感激
我写这篇文章时使用了一些类似的问题来获取给定随机 IP 和掩码的任何子网的第一个和最后一个地址:
Function Get-SubnetAddresses {
Param ([IPAddress]$IP,[ValidateRange(0, 32)][int]$maskbits)
# Convert the mask to type [IPAddress]:
$mask = ([Math]::Pow(2, $MaskBits) - 1) * [Math]::Pow(2, (32 - $MaskBits))
$maskbytes = [BitConverter]::GetBytes([UInt32] $mask)
$DottedMask = [IPAddress]((3..0 | ForEach-Object { [String] $maskbytes[$_] }) -join '.')
# bitwise AND them together, and you've got the subnet ID
$lower = [IPAddress] ( $ip.Address -band $DottedMask.Address )
# We can do a similar operation for the broadcast address
# subnet mask bytes need to be inverted and reversed before adding
$LowerBytes = [BitConverter]::GetBytes([UInt32] $lower.Address)
[IPAddress]$upper = (0..3 | %{$LowerBytes[$_] + ($maskbytes[(3-$_)] -bxor 255)}) -join '.'
# Make an object for use elsewhere
Return [pscustomobject][ordered]@{
Lower=$lower
Upper=$upper
}
}
用法如下:
Get-IPAddresses 10.43.120.8 22
Lower Upper
----- -----
10.43.120.0 10.43.123.255
然后我把它放在一起生成了整个列表。我确信这可以做得更好,但是简单的说明 运行 足够快:
Function Get-IPRange {
param (
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName)][IPAddress]$lower,
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName)][IPAddress]$upper
)
# use lists for speed
$IPList = [Collections.ArrayList]::new()
$null = $IPList.Add($lower)
$i = $lower
# increment ip until reaching $upper in range
while ( $i -ne $upper ) {
# IP octet values are built back-to-front, so reverse the octet order
$iBytes = [BitConverter]::GetBytes([UInt32] $i.Address)
[Array]::Reverse($iBytes)
# Then we can +1 the int value and reverse again
$nextBytes = [BitConverter]::GetBytes([UInt32]([bitconverter]::ToUInt32($iBytes,0) +1))
[Array]::Reverse($nextBytes)
# Convert to IP and add to list
$i = [IPAddress]$nextBytes
$null = $IPList.Add($i)
}
return $IPList
}
在最后一行转换为 [IPAddress]
可以很好地验证所有结果是否真实,但如果您只需要 ipv4 字符串,则可能没有必要。用法:
Get-SubnetAddresses 10.43.120.8 30 | Get-IPRange | Select -ExpandProperty IPAddressToString
10.43.120.8
10.43.120.9
10.43.120.10
10.43.120.11
来源:
我正在尝试根据用户的输入构建一组可能的 IP 地址。即 IP 地址和 CIDR 号码。我的最终目标是将此列表与单独的地址列表进行比较,找出缺少的地址。
例子 用户输入:192.168.1.0 /24 我想为 /24 网络的所有可能值构建一个数组(即 IP 地址可以是 192.168.1.0 - 192.168.1.255 之间的任何位置)
为了让它工作,我想我必须将 IP 地址转换为二进制,然后找到将成为网络主机部分的位,我已在此处完成:
function ConvertToBinary{
param($ipAddress)
[string]$binaryIP = -join ($ipAddress.Split('.') | ForEach-Object {[System.Convert]::ToString($_,2).PadLeft(8,'0')})
return $binaryIP
}
function FindHost{
param(
[string]$binaryIPAddress,
[int32]$CIDR
)
$hostBits = 32-$CIDR
[string]$myHost = $binaryIPAddress.Substring($binaryIPAddress.Length-$hostBits)
return $myHost
}
$myip = ConvertToBinary "192.168.3.1"
$myHost = FindHost $myip 8
我对如何进行有点困惑,所以如果有人能帮助我或指出正确的方向,我将不胜感激
我写这篇文章时使用了一些类似的问题来获取给定随机 IP 和掩码的任何子网的第一个和最后一个地址:
Function Get-SubnetAddresses {
Param ([IPAddress]$IP,[ValidateRange(0, 32)][int]$maskbits)
# Convert the mask to type [IPAddress]:
$mask = ([Math]::Pow(2, $MaskBits) - 1) * [Math]::Pow(2, (32 - $MaskBits))
$maskbytes = [BitConverter]::GetBytes([UInt32] $mask)
$DottedMask = [IPAddress]((3..0 | ForEach-Object { [String] $maskbytes[$_] }) -join '.')
# bitwise AND them together, and you've got the subnet ID
$lower = [IPAddress] ( $ip.Address -band $DottedMask.Address )
# We can do a similar operation for the broadcast address
# subnet mask bytes need to be inverted and reversed before adding
$LowerBytes = [BitConverter]::GetBytes([UInt32] $lower.Address)
[IPAddress]$upper = (0..3 | %{$LowerBytes[$_] + ($maskbytes[(3-$_)] -bxor 255)}) -join '.'
# Make an object for use elsewhere
Return [pscustomobject][ordered]@{
Lower=$lower
Upper=$upper
}
}
用法如下:
Get-IPAddresses 10.43.120.8 22
Lower Upper
----- -----
10.43.120.0 10.43.123.255
然后我把它放在一起生成了整个列表。我确信这可以做得更好,但是简单的说明 运行 足够快:
Function Get-IPRange {
param (
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName)][IPAddress]$lower,
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName)][IPAddress]$upper
)
# use lists for speed
$IPList = [Collections.ArrayList]::new()
$null = $IPList.Add($lower)
$i = $lower
# increment ip until reaching $upper in range
while ( $i -ne $upper ) {
# IP octet values are built back-to-front, so reverse the octet order
$iBytes = [BitConverter]::GetBytes([UInt32] $i.Address)
[Array]::Reverse($iBytes)
# Then we can +1 the int value and reverse again
$nextBytes = [BitConverter]::GetBytes([UInt32]([bitconverter]::ToUInt32($iBytes,0) +1))
[Array]::Reverse($nextBytes)
# Convert to IP and add to list
$i = [IPAddress]$nextBytes
$null = $IPList.Add($i)
}
return $IPList
}
在最后一行转换为 [IPAddress]
可以很好地验证所有结果是否真实,但如果您只需要 ipv4 字符串,则可能没有必要。用法:
Get-SubnetAddresses 10.43.120.8 30 | Get-IPRange | Select -ExpandProperty IPAddressToString
10.43.120.8
10.43.120.9
10.43.120.10
10.43.120.11
来源: