验证IP地址是否在指定的网段内(kotlin版)

可作为工具类直接使用(kotlin版)

package com.ip

import java.util.regex.Matcher
import java.util.regex.Pattern

data class IPAddress(private val binaryValue: Int) : Comparable<IPAddress> {
    override fun compareTo(other: IPAddress): Int =
            Integer.compareUnsigned(binaryValue, other.binaryValue)

    constructor(ip: String) : this(parseIP(ip))

    companion object {
        private const val IP_ADDRESS = "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})"
        private val ipPattern = Pattern.compile(IP_ADDRESS)

        private fun parseIP(ip: String): Int {
            val matcher = ipPattern.matcher(ip)
            require(matcher.matches()) { "Could not parse [$ip]" }

            return matcher.matchAddress()
        }
    }
}

data class IPAddressRange constructor(private val range: ClosedRange<IPAddress>) :
        ClosedRange<IPAddress> by range {

    constructor(cidr: String) : this(parseCIDR(cidr))

    companion object {
        private const val IP_ADDRESS = "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})"
        private const val SLASH_FORMAT = "$IP_ADDRESS/(\\d{1,3})"
        private val cidrPattern = Pattern.compile(SLASH_FORMAT)

        private fun parseCIDR(cidr: String): ClosedRange<IPAddress> {
            val matcher = cidrPattern.matcher(cidr)
            require(matcher.matches()) { "Could not parse [$cidr]" }

            val address = matcher.matchAddress()
            /* Create a binary netmask from the number of bits specification /x */
            val cidrPart: Int = matcher.group(5).toInt().mustBeInRange(IntRange(0, 32))

            val netmask = cidrMasks[cidrPart]
            val network = address and netmask
            return IPAddress(network)..IPAddress(address or netmask.inv())
        }

        private val cidrMasks = 32.calculateBitMasks().toIntArray()

        private fun Int.calculateBitMasks(): List<Int> {
            var current = 0L
            return (0..this).map { bit ->
                current += if (bit == 0) 0
                else 1L shl bit - 1
                current.inv().toInt()
            }.reversed()
        }
    }
}

/**
 * Convenience method to extract the components of a dotted decimal address and
 * pack into an integer using a regex match
 */
fun Matcher.matchAddress(): Int {
    var addr = 0
    for (i in 1..4) {
        val n: Int = this.group(i).toInt().mustBeInRange(0..255)
        addr = addr or (n and 0xff shl 8 * (4 - i))
    }
    return addr
}

/**
 * Convenience function to check integer boundaries.
 * Checks if a value x is in the range [begin,end].
 * Returns x if it is in range, throws an exception otherwise.
 */
fun Int.mustBeInRange(range: IntRange): Int {
    require(range.contains(this)) { "Value $this not in range $range" }
    return this
}

使用:

网段格式为带掩码的ip地址,如:127.0.0.0/24

fun test() {
    val rang = IPAddressRange("127.0.0.24")
    val ip = IPAddress("127.0.0.1")
    val result = ip in rang
    println("Ip is in the rang: $result")
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值