资讯专栏INFORMATION COLUMN

统计两个IP地址之间的IP个数

yanest / 1045人阅读

摘要:问题求两个地址之间的个数,例如,之间的个数算法地址转换成数字数字转换成地址地址转换成数字数字转换成地址查找两个地址之间的原理无论是还是,它们其实都是对应整数值,但是为了方面人的理解和分析,对这个整数采用了某种格式化的方式进行

问题

求两个IP地址之间的IP个数,例如192.18.16.1~192.18.16.5,2001:DB8:0000:0023:0008:0800:200C:417C~2001:DB8:0:23:8:800:200C:417D之间的IP个数?

算法
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

public class IPCount {

    /**
      * IPv4地址转换成数字
      * @param ip
    */
    public long ipv4ToNumber(String ip) {
        long rs = 0;
        if (ip == null || ip.isEmpty()) {
            return rs;
        }
        String[] ips = ip.split(".");
        for (int i = 0; i < ips.length; i++) {
            rs += Integer.parseInt(ips[i]) * Math.pow(256, (3 - i));
        }
        return rs;
    }
    
    /**
     * 数字转换成IPv4地址
     * @param number
     * @return
     */
    public String numberToIpv4(long number) {
        String ip = "";
        List ips = new ArrayList();
        for (int i = 0; i < 8; i++) {
            ips.add(String.valueOf(number % 256));
            number = number >> 8;
        }
        for (int i = ips.size() - 1; i >= 0; i--) {
            ip = ip.concat(ips.get(i));
            if (i > 0) {
                ip = ip.concat(".");
            }
        }
        return ip;
    }
    
    /**
     * IPv6地址转换成数字
     * @param ip
     * @return
     */
    public BigInteger ipv6ToNumber(String ip) {
        String[] ips = ip.split(":");
        BigInteger rs = new BigInteger("0");
        
        for (int i = 0; i < ips.length; i++) {
            BigInteger a = BigInteger.valueOf(Integer.parseInt(ips[i], 16));
            BigInteger b = BigInteger.valueOf(65536).pow(7 - i);
            BigInteger c = a.multiply(b);
            rs = rs.add(c);
        }
        return rs;
    }
    
    /**
     * 数字转换成IPV6地址
     * @param number
     * @return
     */
    public String numberToIpv6(BigInteger number) {
        String ip = "";
        List ips = new ArrayList();
        
        for (int i = 0; i < 8; i++) {
            ips.add(Integer.toHexString(number.divideAndRemainder(BigInteger.valueOf(65536))[1].intValue()));
            number = number.shiftRight(16);
        }
        
        for (int i = ips.size() - 1; i >= 0; i--) {
            ip = ip.concat(ips.get(i));
            if (i > 0) {
                ip = ip.concat(":");
            }
        }
        return ip;
    }
    
    /**
     * 查找两个IP地址之间的IP
     * @param startIp
     * @param endIp
     * @return
     */
    public List findIPs(String startIp, String endIp) {
        BigInteger startNumber = this.ipv6ToNumber(startIp);
        BigInteger endNumber = this.ipv6ToNumber(endIp).add(BigInteger.valueOf(1));
        List ips = new ArrayList();
        while (startNumber.compareTo(endNumber) < 0) {
            ips.add(this.numberToIpv6(startNumber));
            startNumber = startNumber.add(BigInteger.valueOf(1));
        }
        return ips;
    }
}
原理

无论是IPV4还是IPV6,它们其实都是对应整数值,但是为了方面人的理解和分析,对这个整数采用了某种格式化的方式进行表示,比如IPV4是一个32的整数,采用点分十进制的格式表示,IPV6是一个128位的整数,采用冒分十六进制的个数表示,也就是说对于一个给定的32位整数,可以转换成一个IP地址,同样,对于一个给定的IP地址,可以转换成一个32位的整数,所以计算两个IP地址之间的个数或者IP,其实就是计算两个整数之间有多少个整数
只是IPV6对应一个128位的整数,所以使用Java基本的数据类型long是无法存储这么多位的数据的,需要采用了BigInteger

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73292.html

相关文章

  • 记Redis在项目中一个类分时图应用场景设计

    摘要:需求项目有一个保存实时抓拍图片的功能需要统计摄像头下每个时间点比如一分钟保存的图片个数并通过线型图显示到页面上这很类似股票的分时线图的功能所以我参考了一些网上的文章采用来实现这个功能先交代一下项目里数据的一个情况摄像头个数在个左右单个摄像头 需求: 项目有一个保存实时抓拍图片的功能,需要统计摄像头下每个时间点(比如一分钟)保存的图片个数,并通过线型图显示到页面上.这很类似股票的分时K...

    kuangcaibao 评论0 收藏0
  • Python工具分析风险数据

    摘要:小安分析的数据主要是用户使用代理访问日志记录信息,要分析的原始数据以的形式存储。下面小安带小伙伴们一起来管窥管窥这些数据。在此小安一定一定要告诉你,小安每次做数据分析时必定使用的方法方法。 随着网络安全信息数据大规模的增长,应用数据分析技术进行网络安全分析成为业界研究热点,小安在这次小讲堂中带大家用Python工具对风险数据作简单分析,主要是分析蜜罐日志数据,来看看一般大家都使用代理i...

    Berwin 评论0 收藏0
  • ?Echarts统计拉勾网招聘信息(scrapy 爬取)

    摘要:因为本人在成都从事前端,所以这次爬取的关键词既是成都,前端。仅仅有这个是不够的,因为貌似拉勾网有反爬虫,没有好像得不到数据这个还待论证,至少我这边是。 前言 showImg(https://segmentfault.com/img/bV1g4S?w=700&h=490); 今天是2018的第一天,首先祝各位小伙伴元旦快乐!又到了新的一年,虽然离春节还有一段时间,但是程序狗打工不易啊,不...

    genefy 评论0 收藏0
  • ?Echarts统计拉勾网招聘信息(scrapy 爬取)

    摘要:因为本人在成都从事前端,所以这次爬取的关键词既是成都,前端。仅仅有这个是不够的,因为貌似拉勾网有反爬虫,没有好像得不到数据这个还待论证,至少我这边是。 前言 showImg(https://segmentfault.com/img/bV1g4S?w=700&h=490); 今天是2018的第一天,首先祝各位小伙伴元旦快乐!又到了新的一年,虽然离春节还有一段时间,但是程序狗打工不易啊,不...

    Jingbin_ 评论0 收藏0

发表评论

0条评论

yanest

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<