如何在 Scala 中转换 to/from 长的 IPv4 地址
How to Convert IPv4 Addresses to/from Long in Scala
我正在寻找一个具有 2 个函数的基本实用程序,用于在 Scala 中将 IPv4 地址 to/from Long 转换,例如“10.10.10.10”到它的 Long 表示形式 168430090 并返回。许多语言(例如 python)中都存在这样的基本实用程序,但似乎需要为 JVM 的每个人重新编写相同的代码。
统一 IPv4ToLong 和 LongToIPv4 功能的推荐方法是什么?
import java.net.InetAddress
def IPv4ToLong(dottedIP: String): Long = {
val addrArray: Array[String] = dottedIP.split("\.")
var num: Long = 0
var i: Int = 0
while (i < addrArray.length) {
val power: Int = 3 - i
num = num + ((addrArray(i).toInt % 256) * Math.pow(256, power)).toLong
i += 1
}
num
}
def LongToIPv4 (ip : Long) : String = {
val bytes: Array[Byte] = new Array[Byte](4)
bytes(0) = ((ip & 0xff000000) >> 24).toByte
bytes(1) = ((ip & 0x00ff0000) >> 16).toByte
bytes(2) = ((ip & 0x0000ff00) >> 8).toByte
bytes(3) = (ip & 0x000000ff).toByte
InetAddress.getByAddress(bytes).getHostAddress()
}
scala> IPv4ToLong("10.10.10.10")
res0: Long = 168430090
scala> LongToIPv4(168430090L)
res1: String = 10.10.10.10
我有一个 GitHub 要点可以解决这个问题。要点包含从 IP 转换为 Long 的代码,反之亦然。访问 https://gist.github.com/OElesin/f0f2c69530a315177b9e0227a140f9c1
代码如下:
def ipToLong(ipAddress: String): Long = {
ipAddress.split("\.").reverse.zipWithIndex.map(a=>a._1.toInt*math.pow(256,a._2).toLong).sum
}
def longToIP(long: Long): String = {
(0 until 4).map(a=>long / math.pow(256, a).floor.toInt % 256).reverse.mkString(".")
}
享受
添加到 Elesin Olalekan Fuad's 答案可以使它更健壮一点,如下所示:
def ipToLong(ip: String): Option[Long] = {
Try(ip.split('.').ensuring(_.length == 4)
.map(_.toLong).ensuring(_.forall(x => x >= 0 && x < 256))
.zip(Array(256L * 256L * 256L, 256L * 256L, 256L, 1L))
.map { case (x, y) => x * y }
.sum).toOption
}
def longToIp(ip: Long): Option[String] = {
if (ip >= 0 && ip <= 4294967295L)
Some((0 until 4)
.map(a => ip / math.pow(256, a).floor.toInt % 256)
.reverse.mkString("."))
else
None
}
结合leifbatterman and Elesin Olalekan Fuad的思想,避免乘法和幂运算:
def ipv4ToLong(ip: String): Option[Long] = Try(
ip.split('.').ensuring(_.length == 4)
.map(_.toLong).ensuring(_.forall(x => x >= 0 && x < 256))
.reverse.zip(List(0,8,16,24)).map(xi => xi._1 << xi._2).sum
).toOption
要将 Long 转换为点分格式的 String:
def longToipv4(ip: Long): Option[String] = if ( ip >= 0 && ip <= 4294967295L) {
Some(List(0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000).zip(List(0,8,16,24))
.map(mi => ((mi._1 & ip) >> mi._2)).reverse
.map(_.toString).mkString("."))
} else None
这对于 ipv4
来说非常简单:
def ipToLong(ip:String) = ip.split("\\.").foldLeft(0L)((c,n)=>c*256+n.toLong)
def longToIP(ip:Long) = (for(a<-3 to 0 by -1) yield ((ip>>(a*8))&0xff).toString).mkString(".")
试试 ipaddr scala library。创建一个 IpAddress 并像这样获取它的 long 值:
val ip1: IpAddress = IpAddress("192.168.0.1")
val ip1Long = ip1.numerical // returns 3232235521L
我喜欢@jwvh 对 ipv4ToLong 的评论。至于longToIpv4,干脆干脆:
def longToIpv4(v:Long):String = (for (i <- 0 to 3) yield (v >> (i * 8)) & 0x000000FF ).reverse.mkString(".")
我正在寻找一个具有 2 个函数的基本实用程序,用于在 Scala 中将 IPv4 地址 to/from Long 转换,例如“10.10.10.10”到它的 Long 表示形式 168430090 并返回。许多语言(例如 python)中都存在这样的基本实用程序,但似乎需要为 JVM 的每个人重新编写相同的代码。
统一 IPv4ToLong 和 LongToIPv4 功能的推荐方法是什么?
import java.net.InetAddress
def IPv4ToLong(dottedIP: String): Long = {
val addrArray: Array[String] = dottedIP.split("\.")
var num: Long = 0
var i: Int = 0
while (i < addrArray.length) {
val power: Int = 3 - i
num = num + ((addrArray(i).toInt % 256) * Math.pow(256, power)).toLong
i += 1
}
num
}
def LongToIPv4 (ip : Long) : String = {
val bytes: Array[Byte] = new Array[Byte](4)
bytes(0) = ((ip & 0xff000000) >> 24).toByte
bytes(1) = ((ip & 0x00ff0000) >> 16).toByte
bytes(2) = ((ip & 0x0000ff00) >> 8).toByte
bytes(3) = (ip & 0x000000ff).toByte
InetAddress.getByAddress(bytes).getHostAddress()
}
scala> IPv4ToLong("10.10.10.10")
res0: Long = 168430090
scala> LongToIPv4(168430090L)
res1: String = 10.10.10.10
我有一个 GitHub 要点可以解决这个问题。要点包含从 IP 转换为 Long 的代码,反之亦然。访问 https://gist.github.com/OElesin/f0f2c69530a315177b9e0227a140f9c1
代码如下:
def ipToLong(ipAddress: String): Long = {
ipAddress.split("\.").reverse.zipWithIndex.map(a=>a._1.toInt*math.pow(256,a._2).toLong).sum
}
def longToIP(long: Long): String = {
(0 until 4).map(a=>long / math.pow(256, a).floor.toInt % 256).reverse.mkString(".")
}
享受
添加到 Elesin Olalekan Fuad's 答案可以使它更健壮一点,如下所示:
def ipToLong(ip: String): Option[Long] = {
Try(ip.split('.').ensuring(_.length == 4)
.map(_.toLong).ensuring(_.forall(x => x >= 0 && x < 256))
.zip(Array(256L * 256L * 256L, 256L * 256L, 256L, 1L))
.map { case (x, y) => x * y }
.sum).toOption
}
def longToIp(ip: Long): Option[String] = {
if (ip >= 0 && ip <= 4294967295L)
Some((0 until 4)
.map(a => ip / math.pow(256, a).floor.toInt % 256)
.reverse.mkString("."))
else
None
}
结合leifbatterman and Elesin Olalekan Fuad的思想,避免乘法和幂运算:
def ipv4ToLong(ip: String): Option[Long] = Try(
ip.split('.').ensuring(_.length == 4)
.map(_.toLong).ensuring(_.forall(x => x >= 0 && x < 256))
.reverse.zip(List(0,8,16,24)).map(xi => xi._1 << xi._2).sum
).toOption
要将 Long 转换为点分格式的 String:
def longToipv4(ip: Long): Option[String] = if ( ip >= 0 && ip <= 4294967295L) {
Some(List(0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000).zip(List(0,8,16,24))
.map(mi => ((mi._1 & ip) >> mi._2)).reverse
.map(_.toString).mkString("."))
} else None
这对于 ipv4
来说非常简单:
def ipToLong(ip:String) = ip.split("\\.").foldLeft(0L)((c,n)=>c*256+n.toLong)
def longToIP(ip:Long) = (for(a<-3 to 0 by -1) yield ((ip>>(a*8))&0xff).toString).mkString(".")
试试 ipaddr scala library。创建一个 IpAddress 并像这样获取它的 long 值:
val ip1: IpAddress = IpAddress("192.168.0.1")
val ip1Long = ip1.numerical // returns 3232235521L
我喜欢@jwvh 对 ipv4ToLong 的评论。至于longToIpv4,干脆干脆:
def longToIpv4(v:Long):String = (for (i <- 0 to 3) yield (v >> (i * 8)) & 0x000000FF ).reverse.mkString(".")