如何在Scala中将IPv6地址转换为BigInteger和从BigInteger转换IPv6地址

时间:2016-01-11 22:50:16

标签: scala ipv6 biginteger inetaddress

希望将IPv6字符串(例如2001:0:4137:9e76:34b7:2e31:3f57:fd9a)转换为BigInteger,将BigInteger转换为IPv6字符串。

2 个答案:

答案 0 :(得分:4)

import java.math.BigInteger
import java.net.InetAddress
import java.net.Inet6Address
def ipv6ToBigInteger(ipv6 : String) : BigInteger = {
    val ia = InetAddress.getByName(ipv6)
    val byteArr : Array[Byte] = ia.getAddress()
    var ipNumber = new BigInteger("0")
    if (ia.isInstanceOf[Inet6Address]) {
        ipNumber = new BigInteger(1, byteArr)
    }
    return ipNumber
}

def bigIntegerToIPv6(ipv6Num : BigInteger) : String = {
    val ipv6Str = InetAddress.getByAddress(ipv6Num.toByteArray).toString()
    return ipv6Str.replaceFirst("/", "")
}

val ipv6 = "2001:0:4137:9e76:34b7:2e31:3f57:fd9a"
val ipv6Num = ipv6ToBigInteger(ipv6) // ipv6Num: java.math.BigInteger = 42540488182159607633435240198452018586
val ipv6Str = bigIntegerToIPv6(ipv6Num) // ipv6Str: String = 2001:0:4137:9e76:34b7:2e31:3f57:fd9a
ipv6 == ipv6Str // res0: Boolean = true

更新编辑:

根据匿名用户的建议编辑:

“注释:InetAddress.getByAddress需要一个16字节的数组才能解析IPv6地址(IPv4的4字节数组)。实际上,代码对于没有导致16字节的任何值都失败了调用.toByteArray时的数组“

def bigIntToFixedSizeByteArray(n: BigInteger, size: Int = 16): Array[Byte] = {
    val a = n.toByteArray
    val leadingLength = math.max(size - a.length, 0)
    Array.ofDim[Byte](leadingLength) ++ a
}

def bigIntegerToIPv6(ipv6Num : BigInteger) : String = {
    val address = InetAddress.getByAddress(bigIntToFixedSizeByteArray(ipv6Num))  
    address.toString.replaceFirst("/", "")
}

答案 1 :(得分:1)

看看这个(支持ipv4和ipv6):

import java.math.BigInteger
import java.net.{UnknownHostException, InetAddress}
import org.apache.commons.lang.StringUtils

def ipToBigInteger(s: String): BigInteger = {
  try {
    val i = InetAddress.getByName(s)
    val a: Array[Byte] = i.getAddress()
    new BigInteger(1, a)
  } catch {
    case e: UnknownHostException => new BigInteger("-1")
  }
}


def bigIntegerToIP(s: String): String = {
  try {
    //InetAddress.getByAddress(bi.toByteArray).toString.replaceFirst("/", "")
    val bi = new BigInteger(s)
    if (bi.compareTo(new BigInteger("0")) != -1 && bi.compareTo(new   BigInteger("340282366920938463463374607431768211455")) != 1) {
      if (bi.compareTo(new BigInteger("4294967295")) != 1) { // IPV4
        val l = bi.longValue
        String.format("%d.%d.%d.%d",
          bi.shiftRight(24).and(BigInteger.valueOf(0xFF)).intValue: Integer,
          bi.shiftRight(16).and(BigInteger.valueOf(0xFF)).intValue: Integer,
          bi.shiftRight(8).and(BigInteger.valueOf(0xFF)).intValue: Integer,
          bi.and(BigInteger.valueOf(0xFF)).intValue: Integer)
      } else { // IPV6
        String.format("%s:%s:%s:%s:%s:%s:%s:%s",
          Integer.toHexString(bi.shiftRight(112).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
          Integer.toHexString(bi.shiftRight(96).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
          Integer.toHexString(bi.shiftRight(80).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
          Integer.toHexString(bi.shiftRight(64).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
          Integer.toHexString(bi.shiftRight(48).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
          Integer.toHexString(bi.shiftRight(32).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
          Integer.toHexString(bi.shiftRight(16).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
          Integer.toHexString(bi.and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String)
      }
    } else
      StringUtils.EMPTY
  } catch {
    case e: UnknownHostException => StringUtils.EMPTY
    case e: NumberFormatException => StringUtils.EMPTY
  }
}


def bigIntegerToIPV6(bi: BigInteger): String = {
  try {
    //InetAddress.getByAddress(bi.toByteArray).toString.replaceFirst("/", "")
    if (bi.compareTo(new BigInteger("0")) != -1 && bi.compareTo(new BigInteger("340282366920938463463374607431768211455")) != 1) {
      String.format("%s:%s:%s:%s:%s:%s:%s:%s",
        Integer.toHexString(bi.shiftRight(112).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
        Integer.toHexString(bi.shiftRight(96).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
        Integer.toHexString(bi.shiftRight(80).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
        Integer.toHexString(bi.shiftRight(64).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
        Integer.toHexString(bi.shiftRight(48).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
        Integer.toHexString(bi.shiftRight(32).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
        Integer.toHexString(bi.shiftRight(16).and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String,
        Integer.toHexString(bi.and(BigInteger.valueOf(0xFFFF)).intValue): java.lang.String)
    } else
      StringUtils.EMPTY
  } catch {
    case e: UnknownHostException => StringUtils.EMPTY
    case e: NumberFormatException => StringUtils.EMPTY
  }
}