`
lbyzx123
  • 浏览: 478200 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java IPV6、IPV4地址与BigInteger互相转化

    博客分类:
  • java
 
阅读更多

由于项目的需要,需要把 IPV6、IPV4地址转化为BigInteger,也需要将BigInteger转化为 IPV6、IPV4地址。于是上网查找资料。发现网上有一个IpConvert类:于是拷贝下来在项目中应用。
IpConvert的源码如下:

import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

/**
 * IP转换工具
 * 
 * @author Takamachi660
 * 
 */
public final class IpConvert {
	/**
	 * 防止被实例化
	 */
	private IpConvert() {
	}

	/**
	 * 将字符串形式的ip地址转换为BigInteger
	 * 
	 * @param ipInString
	 *            字符串形式的ip地址
	 * @return 整数形式的ip地址
	 */
	public static BigInteger stringToBigInt(String ipInString) {
		ipInString = ipInString.replace(" ", "");
		byte[] bytes;
		if (ipInString.contains(":"))
			bytes = ipv6ToBytes(ipInString);
		else
			bytes = ipv4ToBytes(ipInString);
		return new BigInteger(bytes);
	}

	/**
	 * 将整数形式的ip地址转换为字符串形式
	 * 
	 * @param ipInBigInt
	 *            整数形式的ip地址
	 * @return 字符串形式的ip地址
	 */
	public static String bigIntToString(BigInteger ipInBigInt) {
		byte[] bytes = ipInBigInt.toByteArray();
		byte[] unsignedBytes = Arrays.copyOfRange(bytes, 1, bytes.length);
		// 去除符号位
		try {
			String ip = InetAddress.getByAddress(unsignedBytes).toString();
			return ip.substring(ip.indexOf('/') + 1).trim();
		} catch (UnknownHostException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * ipv6地址转有符号byte[17]
	 */
	private static byte[] ipv6ToBytes(String ipv6) {
		byte[] ret = new byte[17];
		ret[0] = 0;
		int ib = 16;
		boolean comFlag = false;// ipv4混合模式标记
		if (ipv6.startsWith(":"))// 去掉开头的冒号
			ipv6 = ipv6.substring(1);
		String groups[] = ipv6.split(":");
		for (int ig = groups.length - 1; ig > -1; ig--) {// 反向扫描
			if (groups[ig].contains(".")) {
				// 出现ipv4混合模式
				byte[] temp = ipv4ToBytes(groups[ig]);
				ret[ib--] = temp[4];
				ret[ib--] = temp[3];
				ret[ib--] = temp[2];
				ret[ib--] = temp[1];
				comFlag = true;
			} else if ("".equals(groups[ig])) {
				// 出现零长度压缩,计算缺少的组数
				int zlg = 9 - (groups.length + (comFlag ? 1 : 0));
				while (zlg-- > 0) {// 将这些组置0
					ret[ib--] = 0;
					ret[ib--] = 0;
				}
			} else {
				int temp = Integer.parseInt(groups[ig], 16);
				ret[ib--] = (byte) temp;
				ret[ib--] = (byte) (temp >> 8);
			}
		}
		return ret;
	}

	/**
	 * ipv4地址转有符号byte[5]
	 */
	private static byte[] ipv4ToBytes(String ipv4) {
		byte[] ret = new byte[5];
		ret[0] = 0;
		// 先找到IP地址字符串中.的位置
		int position1 = ipv4.indexOf(".");
		int position2 = ipv4.indexOf(".", position1 + 1);
		int position3 = ipv4.indexOf(".", position2 + 1);
		// 将每个.之间的字符串转换成整型
		ret[1] = (byte) Integer.parseInt(ipv4.substring(0, position1));
		ret[2] = (byte) Integer.parseInt(ipv4.substring(position1 + 1,
				position2));
		ret[3] = (byte) Integer.parseInt(ipv4.substring(position2 + 1,
				position3));
		ret[4] = (byte) Integer.parseInt(ipv4.substring(position3 + 1));
		return ret;
	}

	public static void main(String[] args) {
		System.out.println(stringToBigInt("10.36.65.22"));
		System.out.println(bigIntToString(stringToBigInt("10.36.65.22")));
	}
}

 但是,在测试的时候发现10段的ip地址的BigInteger 形式无法转为字符串,经过一番测试将程序改造如下:

import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

/**
 * IP转换工具
 * 
 * @author Takamachi660
 * 
 */
public final class IpConvert {
	/**
	 * 防止被实例化
	 */
	private IpConvert() {
	}

	/**
	 * 将字符串形式的ip地址转换为BigInteger
	 * 
	 * @param ipInString
	 *            字符串形式的ip地址
	 * @return 整数形式的ip地址
	 */
	public static BigInteger stringToBigInt(String ipInString) {
		ipInString = ipInString.replace(" ", "");
		byte[] bytes;
		if (ipInString.contains(":"))
			bytes = ipv6ToBytes(ipInString);
		else
			bytes = ipv4ToBytes(ipInString);
		return new BigInteger(bytes);
	}

	/**
	 * 将整数形式的ip地址转换为字符串形式
	 * 
	 * @param ipInBigInt
	 *            整数形式的ip地址
	 * @return 字符串形式的ip地址
	 */
	public static String bigIntToString(BigInteger ipInBigInt) {
		byte[] bytes = ipInBigInt.toByteArray();
		byte[] unsignedBytes = Arrays.copyOfRange(bytes, 1, bytes.length);
		if (bytes.length == 4 || bytes.length == 16) {
			unsignedBytes = bytes;
		}
		// 去除符号位
		try {
			String ip = InetAddress.getByAddress(unsignedBytes).toString();
			return ip.substring(ip.indexOf('/') + 1).trim();
		} catch (UnknownHostException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * ipv6地址转有符号byte[17]
	 */
	private static byte[] ipv6ToBytes(String ipv6) {
		byte[] ret = new byte[17];
		ret[0] = 0;
		int ib = 16;
		boolean comFlag = false;// ipv4混合模式标记
		if (ipv6.startsWith(":"))// 去掉开头的冒号
			ipv6 = ipv6.substring(1);
		String groups[] = ipv6.split(":");
		for (int ig = groups.length - 1; ig > -1; ig--) {// 反向扫描
			if (groups[ig].contains(".")) {
				// 出现ipv4混合模式
				byte[] temp = ipv4ToBytes(groups[ig]);
				ret[ib--] = temp[4];
				ret[ib--] = temp[3];
				ret[ib--] = temp[2];
				ret[ib--] = temp[1];
				comFlag = true;
			} else if ("".equals(groups[ig])) {
				// 出现零长度压缩,计算缺少的组数
				int zlg = 9 - (groups.length + (comFlag ? 1 : 0));
				while (zlg-- > 0) {// 将这些组置0
					ret[ib--] = 0;
					ret[ib--] = 0;
				}
			} else {
				int temp = Integer.parseInt(groups[ig], 16);
				ret[ib--] = (byte) temp;
				ret[ib--] = (byte) (temp >> 8);
			}
		}
		return ret;
	}

	/**
	 * ipv4地址转有符号byte[5]
	 */
	private static byte[] ipv4ToBytes(String ipv4) {
		byte[] ret = new byte[5];
		ret[0] = 0;
		// 先找到IP地址字符串中.的位置
		int position1 = ipv4.indexOf(".");
		int position2 = ipv4.indexOf(".", position1 + 1);
		int position3 = ipv4.indexOf(".", position2 + 1);
		// 将每个.之间的字符串转换成整型
		ret[1] = (byte) Integer.parseInt(ipv4.substring(0, position1));
		ret[2] = (byte) Integer.parseInt(ipv4.substring(position1 + 1,
				position2));
		ret[3] = (byte) Integer.parseInt(ipv4.substring(position2 + 1,
				position3));
		ret[4] = (byte) Integer.parseInt(ipv4.substring(position3 + 1));
		return ret;
	}

	public static void main(String[] args) {
		System.out.println(stringToBigInt("10.36.65.22"));
		System.out.println(bigIntToString(stringToBigInt("10.36.65.22")));
		System.out.println(stringToBigInt("fe80::8984:de33:85aa:5b81"));
		System.out.println(bigIntToString(new BigInteger(
				"338288524927261089663928186234336861057")));
	}
}

 改造以后,能够适用于10段、172段、192段、127段等绝大多数的BigInteger 形式转为字符串。其中以下代码是我增加的:

if (bytes.length == 4 || bytes.length == 16) {

unsignedBytes = bytes;

 

}

分享到:
评论

相关推荐

    ipv6的ip地址转biginteger数字

    ipv6的ip地址转biginteger数字 直接能够测试

    java IPv6缩写和非缩写转化方法类

    类中completionIpV6()为补全缩写ipv6,simplifyIpV6()为将全ipv6转化为缩写

    ipv4和ipv6字符串转换成数字

    根据给定的信息,本文将详细解释如何将IPv4与IPv6地址从字符串形式转换为`BigInteger`数字形式,以及反向操作的过程。 ### IPv4与IPv6简介 #### IPv4 IPv4(Internet Protocol Version 4)是互联网协议的第四版,...

    java对ipv6格式的压缩简化以及解析

    这是本人参照如下http://www.gestioip.net/cgi-bin/subnet_calculator.cgi的IPV6解析网站,自己做java的工具类。可以对各种IPV6的格式进行解析。校验。以及对IPV6格式的压缩、以及补全。总之是全网最好用的工具类

    ipv6转换string和byte

    ipv6的byte【】和string间转换类实现及检查

    java-BigInteger-BigDecimal类源码

    在Java编程语言中,`BigInteger`和`BigDecimal`是两个重要的类,它们分别用于处理大整数和高精度浮点数。这两个类位于`java.math`包下,为开发者提供了超越基本数据类型(如int、long和double)的计算能力。在深入...

    java练习_大数运算_BigInteger.pdf

    Java大数运算 BigInteger 类的方法调用 正如我们在 Java 中处理大数运算时,需要使用 BigInteger 类来实现,这是因为 Java 的基本数据类型无法存储非常大的数字。BigInteger 类提供了几个重要的方法来进行大数运算...

    RSA.rar_BigInteger_RSA BigInteger_RSA java biginteger_RSA 类 java

    在Java中,我们可以使用`java.math.BigInteger`类来处理大整数,这在实现RSA算法时非常关键,因为加密过程中涉及的数字通常超过了普通整型变量的范围。以下是关于`BigInteger`类以及如何在Java中实现RSA加解密的详细...

    JAVABigInteger包.pdf

    BigInteger 包是 Java 语言中用于处理大整数的类库。该类库提供了多种构造方法和运算方法来处理大整数。 构造方法 BigInteger 类提供了多种构造方法来创建 BigInteger 对象。这些方法包括: * `BigInteger(byte[]...

    Java大数字运算之BigInteger <font color=red>原创</font>

    Java中的BigInteger类是用于处理大整数运算的重要工具,它弥补了Integer类在处理超过int类型范围(2^31-1)数值时的局限性。BigInteger类支持任意精度的整数运算,这意味着它可以准确地表示和计算非常大的数值,无论...

    Java中BigInteger方法总结

    ### Java中的BigInteger方法详解 #### 一、引言 在Java中处理大整数运算时,`BigInteger` 类提供了一种高效且灵活的方式。与基本数据类型如 `int` 和 `long` 不同,`BigInteger` 可以表示任意大小的整数,只要不...

    关于Biginteger的分数类期末课程设计

    在Java编程语言中,BigInteger类是用于处理大整数的一种数据类型,它可以处理超过long类型所能表示的最大值的整数。在"关于Biginteger的分数类期末课程设计"这个项目中,你创建了一个分数类,其中分子和分母都是用...

    Java中BigInteger.docx

    在Java编程语言中,`BigInteger` 类是用来处理大整数的,它支持任意精度的整数运算。这个类是 `java.math` 包的一部分,它提供了比 `int` 和 `long` 更大的范围,可以用来处理超过64位的整数值。在处理大数据量的...

    java练习_大数运算_BigInteger[参考].pdf

    Java大数运算_BigInteger类的使用 Java大数运算是Java语言中用于处理大整数的运算,以BigInteger类为代表。在Java中,BigInteger类提供了多种方法来处理大整数,包括加、减、乘、除、求余数等操作。 BigInteger类...

    BigInteger

    用java写的BigInteger,主要是实现一个内库

    浅析java.math.BigInteger构造过程.pdf

    "浅析java.math.BigInteger构造过程" java.math.BigInteger 是 Java 标准库中一个非常重要的类,它能够表示任意精度的整数,并在其上进行常见的数学运算。下面我们将对 BigInteger 的构造过程进行详细的分析。 ...

Global site tag (gtag.js) - Google Analytics