簡體   English   中英

IPv6ToBigInteger

[英]IPv6ToBigInteger

我有這個使用InetAddress的 function ,但 output 偶爾會出錯。 (例如: "::ffff:49e7:a9b2"將給出不正確的結果。)

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

我也有這個 function

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
}

這似乎有一個解析錯誤,因為它給出了錯誤的 output 除非它是0:0:0:0:0:0:0:0格式,但它基於我的 IPv4ToLong function:

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 地址 forms。

這是我的嘗試。

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 forms,但使用正則表達式之類的工具並不是一件容易的事。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM