微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

IPv6ToBigInteger

如何解决IPv6ToBigInteger

我有这个使用 InetAddress函数,但输出偶尔会出错。 (例如:"::ffff:49e7:a9b2" 会给出错误的结果。)

def IPv6ToBigInteger(ip: String): BigInteger = {
        val i = InetAddress.getByName(ip)
        val a: Array[Byte] = i.getAddress
        new BigInteger(1,a)
    }

而且我也有这个功能

def IPv6ToBigInteger(ip: String): BigInteger = {
    val fragments = ip.split(":|\\.|::").filter(_.nonEmpty)
    require(fragments.length <= 8,"Bad IPv6")
    var ipNum = new BigInteger("0")
    for (i <-fragments.indices) {
        val frag2Long = new BigInteger(s"${fragments(i)}",16)
        ipNum = frag2Long.or(ipNum.shiftLeft(16))
    }
    ipNum
}

它似乎有一个解析错误,因为它给出了错误输出,除非它是 0:0:0:0:0:0:0:0 格式,但它是基于我的 IPv4ToLong 函数

def IPv4ToLong(ip: String): Long = {
        val fragments = ip.split('.')
        var ipNum = 0L
        for (i <- fragments.indices) {
            val frag2Long = fragments(i).toLong
            ipNum = frag2Long | ipNum << 8L
        }
        ipNum
    }

解决方法

这个

ipNum = frag2Long | ipNum << 8L

ipNum = (frag2Long | ipNum) << 8L

不是

ipNum = frag2Long | (ipNum << 8L)

[ 并且请使用 foldLeft 而不是 varwhile ]

,

有趣的挑战:将 IP 地址字符串转换为 BigInt 值,允许所有合法的 IPv6 地址形式。

这是我的尝试。

import scala.util.Try

def iPv62BigInt(ip: String): Try[BigInt] = Try{
  val fill = ":0:" * (8 - ip.split("[:.]").count(_.nonEmpty))
  val fullArr =
    raw"((?<=\.)(\d+)|(\d+)(?=\.))".r
      .replaceAllIn(ip,_.group(1).toInt.toHexString)
      .replace("::",fill)
      .split("[:.]")
      .collect{case s if s.nonEmpty => s"000$s".takeRight(4)}

  if (fullArr.length == 8) BigInt(fullArr.mkString,16)
  else throw new NumberFormatException("wrong number of elements")
}

诚然,这有点宽松,因为它不会捕获所有非 IPv6 形式,但这不是使用正则表达式等工具的微不足道的任务。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。