我有包含与 IPv6 相关的 IP 号码的 CSV,我正在阅读并将它们转换为目前失败的 IPv6 IP 地址。
我正在使用以下代码但出现错误:
无法将值“281470698520576”转换为类型“System.Net.IPAddress”。错误:“指定的参数是 超出有效值范围。
function Convert-NumberToIP
{
param(
[Parameter(Mandatory=$true)][string]$number
)
[Int64] $numberInt = 0
if([Int64]::TryParse($number, [ref]$numberInt))
{
if(($numberInt -ge 0) -and ($numberInt -le 0xFFFFFFFFl))
{
#([IPAddress] $numberInt).ToString()
$ipBytes = ([IPAddress]$numberInt).GetAddressBytes()
[array]::Reverse($ipBytes)
([IPAddress]$ipBytes).IPAddressToString
}
}
}
$startIP = Convert-NumberToIP -number '281470698520576'
$endIP = Convert-NumberToIP -number '281470698520580'
要在 PowerShell 中使用 128 位整数,您可以利用 .NET
System.Numerics.BigInteger
类。像这样:
$ipv6Decimal = [System.Numerics.BigInteger]::Parse($number)
然后您可以使用
BigInt
将 byte array
转换为 ToByteArray()
。
然而,生成的数组需要“填充”到 16 个字节并反转(主机与网络顺序)。
这对我有用:
function Convert-NumberToIPv6
{
param(
[Parameter(Mandatory=$true)][string]$number
)
$ipv6Decimal = [System.Numerics.BigInteger]::Parse($number)
$ipv6Bytes = $ipv6Decimal.ToByteArray()
# pad to 16 bytes
[Array]::Resize([ref]$ipv6Bytes, 16)
# reverse the bytes
[Array]::Reverse($ipv6Bytes)
# provide a scope identifier to prevent "cannot find overload error"
$ipAddress = New-Object Net.IPAddress($ipv6Bytes, 0)
$ipAddress.ToString()
}
所以输出:
Convert-NumberToIPv6 -number '281470698520576'
是::ffff:1.0.0.0
使用 PowerShell 7+,这是一个可能的实现,其工作方式类似于您问题中的函数,因为将检测到无效输入并且不会导致异常。在这种情况下,函数返回“无”,在布尔上下文中转换为
$false
。
如果您需要与 Windows PowerShell (5.x) 的兼容性,请查看这个答案。
function Convert-NumberToIPv6
{
param(
[Parameter(Mandatory)] [string] $number
)
[Numerics.BigInteger] $bigInt = 0
if( [Numerics.BigInteger]::TryParse( $number, [ref] $bigInt ) ) {
# Check that input is in the range of an unsigned 128 bit number
if( $bigInt.Sign -ge 0 -and $bigInt.GetBitLength() -le 128 ) {
$bytes = $bigInt.ToByteArray($true, $true) # unsigned, big-endian
$zeros = @(0) * (16 - $bytes.Length) # zeros to preprend to ensure 128 bit length
$bytes = [byte[]] ($zeros + $bytes) # prepend zeros
([IPAddress] $bytes).ToString() # convert to IPAddress and then to string
}
}
}
用法:
if( $ipv6 = Convert-NumberToIPv6 '281470698520576' ) {
# Conversion successful, output the address in text form
$ipv6
}
else {
"IPv6 conversion failed!"
}
输出:
::ffff:1.0.0.0