将 IPv6 CIDR 解析为 Powershell 中的第一个地址和最后一个地址
Parsing IPv6 CIDR into first address and last address in Powershell
我正在尝试将使用 CIDR 表示法提供的给定 IPv6 范围转换为 Powershell 中的范围 (first_address-last_address),但有点不顺利。
源数据样本:
2a01:111:f406:c00::/64
2a01:111:f400:7c00::/54
2a01:111:f403::/48
所需输出示例(不需要精确,我可以乱用格式:
2a01:111:f406:c00::-2a01:111:f406:c00:ffff:ffff:ffff:ffff
2a01:111:f400:7c00::-2a01:111:f400:7fff:ffff:ffff:ffff:ffff
2a01:111:f403:0:0:0:0:0::-2a01:111:f403:ffff:ffff:ffff:ffff:ffff
我在谷歌上进行了大量搜索,但没有找到任何能为我指明正确方向的 powershell - 我找到了一个 php 和 js 示例,但翻译得不好。
有什么指点吗?
谢谢!
AFAIK,BCL 中没有任何内容可以解析 IPv6 网段 - 我会使用 IPNetwork
library(适用于 IPv4 和 6):
Add-Type -Path C:\path\to\System.Net.IPNetwork.dll
# Parse ipv6/cidr string
$Network = [System.Net.IPNetwork]::Parse('2a01:111:f400:7c00::/54')
# Format string with first and last usable address
$Range = '{0}-{1}' -f $Network.FirstUsable,$Network.LastUsable
我最终得到了这个,其中 $ipv6cidr 是一个 CIDR 格式的 ipv6 地址数组...
#convert IPv6 CIDR to IPv6 range
$ipv6range=@()
foreach($ip in $ipv6cidr){
$binip=@()
$netbits=$ip.Split("/")[1]
$ip = $ip.Split("/")[0]
$ip=$ip -replace '::',''
$ip=$ip.Split(':')
foreach($p in $ip){
$p='0x'+$p
$bin=[Convert]::ToString($p, 2).PadLeft(16,'0')
$binip+=$bin
}
$binip=$binip -join ''
If($binip.Length -lt $netbitslength)
{
$difference=$netbitslength-$binip.Length
$missing= "1" * $difference
[string]$missing=$missing
$missing=$missing.Padleft(16,'0')
$binip=$binip+$missing
$binip=$binip -replace ',',''
$binstart=$binip.PadRight(128,'0')
$binend=$binip.PadRight(128,'1')
}
elseIf($binip.Length -gt $netbitslength){
$binstart=$binip.substring(0,$netbits).padright(128,'0')
$binend= $binip.substring(0,$netbits).padright(128,'1')
}
$startbin=@()
While ($binstart)
{
$x,$binstart= ([char[]]$binstart).where({$_},'Split',16)
$startbin+=$x -join ''
}
$starts=@()
foreach($start in $startbin){
$start=[Convert]::ToInt32("$start",2)
$starts+='{0:X4}' -f $start
}
$finalstartip=$starts -join ':'
$endbin=@()
While ($binend)
{
$x,$binend= ([char[]]$binend).where({$_},'Split',16)
$endbin+=$x -join ''
}
$ends=@()
foreach($end in $endbin){
$end=[Convert]::ToInt32("$end",2)
$ends+='{0:X4}' -f $end
}
$finalendip=$ends -join ':'
$ipv6range+=$finalstartip+'-'+$finalendip
}
#I had Troubles so I fixed some things:
$AllAddresses = '::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'
$ipv6cidr = $_
if ($ipv6cidr -match "[0-9a-f:]+[:]" -and $_ -ne $AllAddresses) {
$EndBinaryArray = $StartBinaryArray = $null
$NetBits = $($ipv6cidr.Split("/").Replace('::', ''))[1]
#Convert To Binary
$BinaryEquivalent = $(($ipv6cidr.Split("/").Replace('::', ''))[0].Split(':').ForEach(
{
$Decimal = '0x' + $_
[Convert]::ToString($([Uint32]($Decimal)), 2).PadLeft(16, '0')
}
)
)
$BitLength = $BinaryEquivalent.length * 16
$HostId = $BinaryEquivalent -join ""
#Adjust for NetMask
if ($Netbits -lt $BitLength) {
$Difference = $BitLength - $NetBits
$HostnetworkId = $HostId -Replace ".{$Difference}$"
}
if ($Netbits -gt $BitLength) {
$Difference = $Netbits - $BitLength
$HostnetworkId = [String]::Format("$HostId{0}", $("0" * $Difference))
}
if ($Netbits -eq $BitLength) {
$HostnetworkId = $HostId
}
$BinaryStart = $HostnetworkId.PadRight(128, '0')
$BinaryEnd = $HostnetworkId.PadRight(128, '1')
#Convert Back to Decimal then to Hex
While ($BinaryStart) {
$Bytes, $BinaryStart = ([char[]]$BinaryStart).where( { $_ }, 'Split', 16)
[Array]$StartBinaryArray += $Bytes -join ''
}
$HexStartArray = ($StartBinaryArray.ForEach( { '{0:X4}' -f $([Convert]::ToInt32("$_", 2)) })) -join ":"
While ($BinaryEnd) {
$Bytes, $BinaryEnd = ([char[]]$BinaryEnd).where( { $_ }, 'Split', 16)
[Array]$EndBinaryArray += $Bytes -join ''
}
$HexEndArray = ($EndBinaryArray.ForEach( { '{0:X4}' -f $([Convert]::ToInt32("$_", 2)) })) -join ":"
"[{0}] Start: {1} End: {2}" -f $ipv6cidr, $HexStartArray, $HexEndArray
}
if ($ipv6cidr -eq $AllAddresses) {
"[{0}] Start: {1} End: {2}" -f $ipv6cidr, '000:000:000:0000:0000:0000:0000', 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'
}
我正在尝试将使用 CIDR 表示法提供的给定 IPv6 范围转换为 Powershell 中的范围 (first_address-last_address),但有点不顺利。
源数据样本:
2a01:111:f406:c00::/64
2a01:111:f400:7c00::/54
2a01:111:f403::/48
所需输出示例(不需要精确,我可以乱用格式:
2a01:111:f406:c00::-2a01:111:f406:c00:ffff:ffff:ffff:ffff
2a01:111:f400:7c00::-2a01:111:f400:7fff:ffff:ffff:ffff:ffff
2a01:111:f403:0:0:0:0:0::-2a01:111:f403:ffff:ffff:ffff:ffff:ffff
我在谷歌上进行了大量搜索,但没有找到任何能为我指明正确方向的 powershell - 我找到了一个 php 和 js 示例,但翻译得不好。
有什么指点吗?
谢谢!
AFAIK,BCL 中没有任何内容可以解析 IPv6 网段 - 我会使用 IPNetwork
library(适用于 IPv4 和 6):
Add-Type -Path C:\path\to\System.Net.IPNetwork.dll
# Parse ipv6/cidr string
$Network = [System.Net.IPNetwork]::Parse('2a01:111:f400:7c00::/54')
# Format string with first and last usable address
$Range = '{0}-{1}' -f $Network.FirstUsable,$Network.LastUsable
我最终得到了这个,其中 $ipv6cidr 是一个 CIDR 格式的 ipv6 地址数组...
#convert IPv6 CIDR to IPv6 range
$ipv6range=@()
foreach($ip in $ipv6cidr){
$binip=@()
$netbits=$ip.Split("/")[1]
$ip = $ip.Split("/")[0]
$ip=$ip -replace '::',''
$ip=$ip.Split(':')
foreach($p in $ip){
$p='0x'+$p
$bin=[Convert]::ToString($p, 2).PadLeft(16,'0')
$binip+=$bin
}
$binip=$binip -join ''
If($binip.Length -lt $netbitslength)
{
$difference=$netbitslength-$binip.Length
$missing= "1" * $difference
[string]$missing=$missing
$missing=$missing.Padleft(16,'0')
$binip=$binip+$missing
$binip=$binip -replace ',',''
$binstart=$binip.PadRight(128,'0')
$binend=$binip.PadRight(128,'1')
}
elseIf($binip.Length -gt $netbitslength){
$binstart=$binip.substring(0,$netbits).padright(128,'0')
$binend= $binip.substring(0,$netbits).padright(128,'1')
}
$startbin=@()
While ($binstart)
{
$x,$binstart= ([char[]]$binstart).where({$_},'Split',16)
$startbin+=$x -join ''
}
$starts=@()
foreach($start in $startbin){
$start=[Convert]::ToInt32("$start",2)
$starts+='{0:X4}' -f $start
}
$finalstartip=$starts -join ':'
$endbin=@()
While ($binend)
{
$x,$binend= ([char[]]$binend).where({$_},'Split',16)
$endbin+=$x -join ''
}
$ends=@()
foreach($end in $endbin){
$end=[Convert]::ToInt32("$end",2)
$ends+='{0:X4}' -f $end
}
$finalendip=$ends -join ':'
$ipv6range+=$finalstartip+'-'+$finalendip
}
#I had Troubles so I fixed some things:
$AllAddresses = '::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'
$ipv6cidr = $_
if ($ipv6cidr -match "[0-9a-f:]+[:]" -and $_ -ne $AllAddresses) {
$EndBinaryArray = $StartBinaryArray = $null
$NetBits = $($ipv6cidr.Split("/").Replace('::', ''))[1]
#Convert To Binary
$BinaryEquivalent = $(($ipv6cidr.Split("/").Replace('::', ''))[0].Split(':').ForEach(
{
$Decimal = '0x' + $_
[Convert]::ToString($([Uint32]($Decimal)), 2).PadLeft(16, '0')
}
)
)
$BitLength = $BinaryEquivalent.length * 16
$HostId = $BinaryEquivalent -join ""
#Adjust for NetMask
if ($Netbits -lt $BitLength) {
$Difference = $BitLength - $NetBits
$HostnetworkId = $HostId -Replace ".{$Difference}$"
}
if ($Netbits -gt $BitLength) {
$Difference = $Netbits - $BitLength
$HostnetworkId = [String]::Format("$HostId{0}", $("0" * $Difference))
}
if ($Netbits -eq $BitLength) {
$HostnetworkId = $HostId
}
$BinaryStart = $HostnetworkId.PadRight(128, '0')
$BinaryEnd = $HostnetworkId.PadRight(128, '1')
#Convert Back to Decimal then to Hex
While ($BinaryStart) {
$Bytes, $BinaryStart = ([char[]]$BinaryStart).where( { $_ }, 'Split', 16)
[Array]$StartBinaryArray += $Bytes -join ''
}
$HexStartArray = ($StartBinaryArray.ForEach( { '{0:X4}' -f $([Convert]::ToInt32("$_", 2)) })) -join ":"
While ($BinaryEnd) {
$Bytes, $BinaryEnd = ([char[]]$BinaryEnd).where( { $_ }, 'Split', 16)
[Array]$EndBinaryArray += $Bytes -join ''
}
$HexEndArray = ($EndBinaryArray.ForEach( { '{0:X4}' -f $([Convert]::ToInt32("$_", 2)) })) -join ":"
"[{0}] Start: {1} End: {2}" -f $ipv6cidr, $HexStartArray, $HexEndArray
}
if ($ipv6cidr -eq $AllAddresses) {
"[{0}] Start: {1} End: {2}" -f $ipv6cidr, '000:000:000:0000:0000:0000:0000', 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'
}