如何使用 PowerShell 将 IP 号码转换为 IPV6?

问题描述 投票:0回答:2

我有包含与 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 ip ipv6 ip2location
2个回答
3
投票

要在 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


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
© www.soinside.com 2019 - 2024. All rights reserved.