Java中Ipv4与Ipv6的转换「建议收藏」

IPConvert.java类的主要作用是将ip(ipv6\ipv4)转换成16个字节的数组,其中ipv4的转换是先将v4地址转换成v6再转换成长度是16的字节数组 packagecom.cvicse.naba.common.utils;/****描述:*<p>*   &n…

大家好,又见面了,我是你们的朋友全栈君。

IPConvert.java类的主要作用是将ip(ipv6\ipv4)转换成16个字节的数组,其中ipv4的转换是先将v4地址转换成v6再转换成长度是16的字节数组

 

package com.cvicse.naba.common.utils;

/**
 * 
 * 描述:
 * <p>
 * &nbsp;&nbsp;&nbsp;&nbsp;ip转换byte数组管理类。
 * </p>
 * 创建日期:2012-7-25 下午3:34:00<br>
 * 
 * @author:Wendy<br>
 * @update:$Date: 2012-07-25 18:14:40 +0800 (Wed, 25 Jul 2012) $<br>
 * @version:$Revision: 779 $<br>
 * @since 1.0.0
 */
public class IPConvert {
	private static final int IPV6Length = 8; // IPV6地址的分段
	private static final int IPV4Length = 4; // IPV6地址分段
	private static final int IPV4ParmLength = 2; // 一个IPV4分段占的长度
	private static final int IPV6ParmLength = 4; // 一个IPV6分段占的长

	/**
	 * IPV6、IPV4转化为十六进制串
	 * 
	 * @param ipAddress
	 * @return
	 */
	private static String buildKey(String ipAddress) {
		String Key = "";
		// ipv4标识 。判断是否是ipv4地址
		int dotFlag = ipAddress.indexOf(".");
		// ipv6标识 。判断是否是ipv6地址
		int colonFlag = ipAddress.indexOf(":");
		// ipv6标识 。判断是否是简写的ipv6地址
		int dColonFlag = ipAddress.indexOf("::");
		// 将v6或v4的分隔符用&代替
		ipAddress = ipAddress.replace(".", "&");
		ipAddress = ipAddress.replace(":", "&");
		// ipv4 address。将ipv4地址转换成16进制的形式
		if (dotFlag != -1 && colonFlag == -1) {
			String[] arr = ipAddress.split("&");
			// 1、 ipv4转ipv6,前4组数补0或f
			for (int i = 0; i < IPV6Length - IPV4ParmLength; i++) {
				// 根据v4转v6的形式,除第4组数补ffff外,前3组数补0000
				if (i == IPV6Length - IPV4ParmLength - 1) {
					Key += "ffff";
				} else {
					Key += "0000";
				}
			}
			// 2、将ipv4地址转成16进制
			for (int j = 0; j < IPV4Length; j++) {
				// 1)将每组ipv4地址转换成16进制
				arr[j] = Integer.toHexString(Integer.parseInt(arr[j]));
				// 2) 位数不足补0,ipv4地址中一组可转换成一个十六进制,两组数即可标识ipv6中的一组,v6中的一组数不足4位补0
				for (int k = 0; k < (IPV4ParmLength - arr[j].length()); k++) {
					Key += "0";
				}
				Key += arr[j];
			}
		}
		// Mixed address with ipv4 and ipv6。将v4与v6的混合地址转换成16进制的形式
		if (dotFlag != -1 && colonFlag != -1 && dColonFlag == -1) {
			String[] arr = ipAddress.split("&");

			for (int i = 0; i < IPV6Length - IPV4ParmLength; i++) {
				// 将ip地址中每组不足4位的补0
				for (int k = 0; k < (IPV6ParmLength - arr[i].length()); k++) {
					Key += "0";
				}
				Key += arr[i];
			}

			for (int j = 0; j < IPV4Length; j++) {
				arr[j] = Integer.toHexString(Integer.parseInt(arr[j]));
				for (int k = 0; k < (IPV4ParmLength - arr[j].length()); k++) {
					Key += "0";
				}
				Key += arr[j];
			}
		}
		// Mixed address with ipv4 and ipv6,and there are more than one
		// '0'。将v4与v6的混合地址(如::32:dc:192.168.62.174)转换成16进制的形式
		// address param
		if (dColonFlag != -1 && dotFlag != -1) {
			String[] arr = ipAddress.split("&");
			// 存放16进制的形式
			String[] arrParams = new String[IPV6Length + IPV4ParmLength];
			int indexFlag = 0;
			int pFlag = 0;
			// 1、将简写的ip地址补0
			// 如果ip地址中前面部分采用简写,做如下处理
			if ("".equals(arr[0])) {
				// 1)如果ip地址采用简写形式,不足位置补0,存放到arrParams中
				for (int j = 0; j < (IPV6Length + IPV4ParmLength - (arr.length - 2)); j++) {
					arrParams[j] = "0000";
					indexFlag++;
				}
				// 2)将已有值的部分(如32:dc:192.168.62.174)存放到arrParams中
				for (int i = 2; i < arr.length; i++) {
					arrParams[indexFlag] = arr[i];
					indexFlag++;
				}
			} else {
				for (int i = 0; i < arr.length; i++) {
					if ("".equals(arr[i])) {
						for (int j = 0; j < (IPV6Length + IPV4ParmLength
								- arr.length + 1); j++) {
							arrParams[indexFlag] = "0000";
							indexFlag++;
						}
					} else {
						arrParams[indexFlag] = arr[i];
						indexFlag++;
					}
				}
			}
			// 2、ip(去除ipv4的部分)中采用4位十六进制数表示一组数,将不足4位的十六进制数补0
			for (int i = 0; i < IPV6Length - IPV4ParmLength; i++) {
				// 如果arrParams[i]组数据不足4位,前补0
				for (int k = 0; k < (IPV6ParmLength - arrParams[i].length()); k++) {
					Key += "0";
				}
				Key += arrParams[i];
				// pFlag用于标识位置,主要用来标识ipv4地址的起始位
				pFlag++;
			}
			// 3、将ipv4地址转成16进制
			for (int j = 0; j < IPV4Length; j++) {
				// 1)将每组ipv4地址转换成16进制
				arrParams[pFlag] = Integer.toHexString(Integer
						.parseInt(arrParams[pFlag]));
				// 2)位数不足补0,ipv4地址中一组可转换成一个十六进制,两组数即可标识ipv6中的一组,v6中的一组数不足4位补0
				for (int k = 0; k < (IPV4ParmLength - arrParams[pFlag].length()); k++) {
					Key += "0";
				}
				Key += arrParams[pFlag];
				pFlag++;
			}
		}
		// ipv6 address。将ipv6地址转换成16进制
		if (dColonFlag == -1 && dotFlag == -1 && colonFlag != -1) {
			String[] arrParams = ipAddress.split("&");
			// 将v6地址转成十六进制
			for (int i = 0; i < IPV6Length; i++) {
				// 将ipv6地址中每组不足4位的补0
				for (int k = 0; k < (IPV6ParmLength - arrParams[i].length()); k++) {
					Key += "0";
				}

				Key += arrParams[i];
			}
		}

		if (dColonFlag != -1 && dotFlag == -1) {
			String[] arr = ipAddress.split("&");
			String[] arrParams = new String[IPV6Length];
			int indexFlag = 0;
			if ("".equals(arr[0])) {
				for (int j = 0; j < (IPV6Length - (arr.length - 2)); j++) {
					arrParams[j] = "0000";
					indexFlag++;
				}
				for (int i = 2; i < arr.length; i++) {
					arrParams[indexFlag] = arr[i];
					i++;
					indexFlag++;
				}
			} else {
				for (int i = 0; i < arr.length; i++) {
					if ("".equals(arr[i])) {
						for (int j = 0; j < (IPV6Length - arr.length + 1); j++) {
							arrParams[indexFlag] = "0000";
							indexFlag++;
						}
					} else {
						arrParams[indexFlag] = arr[i];
						indexFlag++;
					}
				}
			}
			for (int i = 0; i < IPV6Length; i++) {
				for (int k = 0; k < (IPV6ParmLength - arrParams[i].length()); k++) {
					Key += "0";
				}
				Key += arrParams[i];
			}
		}
		return Key;
	}

	/**
	 * 十六进制串转化为IP地址
	 * 
	 * @param key
	 * @return
	 */
	private static String splitKey(String key) {
		String IPV6Address = "";
		String IPAddress = "";
		String strKey = "";
		String ip1 = key.substring(0, 24);
		String tIP1 = ip1.replace("0000", "").trim();
		if (!"".equals(tIP1) && !"FFFF".equals(tIP1)) {
			// 将ip按:分隔
			while (!"".equals(key)) {
				strKey = key.substring(0, 4);
				key = key.substring(4);
				if ("".equals(IPV6Address)) {
					IPV6Address = strKey;
				} else {
					IPV6Address += ":" + strKey;
				}
			}
			IPAddress = IPV6Address;
		}
		return IPAddress;
	}

	/**
	 * 将ip地址都转成16个字节的数组。先将v6地址存以":"分隔存放到数组中,再将数组中的每两位取存到长度为16的字符串数组中,
	 * 再将这两位十六进制数转成十进制,再转成byte类型存放到16个字的数组中。
	 * 
	 * @param ip
	 * @return
	 */
	public static byte[] toByte(String ip) {
		// 将ip地址转换成16进制
		String Key = buildKey(ip);
		// 将16进制转换成ip地址
		String ip6 = splitKey(Key);

		// 将v6f地址存以":"分隔存放到数组中
		String[] ip6Str = ip6.split(":");
		String[] ipStr = new String[16];
		byte[] ip6Byte = new byte[16];

		// 将数组中的每两位取存到长度为16的字符串数组中
		for (int j = 0, i = 0; i < ip6Str.length; j = j + 2, i++) {
			ipStr[j] = ip6Str[i].substring(0, 2);
			ipStr[j + 1] = ip6Str[i].substring(2, 4);
		}

		// 将ipStr中的十六进制数转成十进制,再转成byte类型存放到16个字的数组中
		for (int i = 0; i < ip6Byte.length; i++) {
			ip6Byte[i] = (byte) Integer.parseInt(ipStr[i], 16);
		}
		return ip6Byte;
	}

}

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/125762.html原文链接:https://javaforall.net

(0)
上一篇 2022年4月6日 上午6:20
下一篇 2022年4月6日 上午6:40


相关推荐

  • 移动端开发技术浅析

    移动端开发技术浅析移动端开发技术浅析目录APK下载概述技术介绍技术对比参考资料1.APK下载百度云链接:https://pan.baidu.com/s/1pLp44Fh2.概述“一次编码,处处运行”永远是程序员们的理想乡。二十年前Java正是举着这面大旗登场,击败了众多竞争对手。但是时至今日,事实已经证明了Java笨重的体型和缓慢的发展显然已经很难再抓住这个时代快速跃动的脚步。在

    2022年6月24日
    27
  • 手把手教你在ARM嵌入式开发板上只做自己的人脸识别装置

    手把手教你在ARM嵌入式开发板上只做自己的人脸识别装置一下是自己一步步构建的嵌入式

    2026年3月19日
    2
  • PHP 数组截取 array_slice() 函数

    PHP 数组截取 array_slice() 函数定义和用法array_slice()函数在数组中根据条件取出一段值,并返回。注释:如果数组有字符串键,所返回的数组将保留键名。(参见例子4)语法array_slice(array,offset,length,preserve)参数array必需。规定输入的数组。offset必需。数值。规定取出元素的开始位置。如果是正数,则从前往后开始取,如果是负值,从

    2022年5月17日
    45
  • Lena图像原图及由来[通俗易懂]

    Lena图像原图及由来[通俗易懂]莱娜图在数字图像处理学习与研究中颇为知名,常被用作数字图像处理各种实验的例图。

    2022年6月19日
    44
  • Android Layout 布局属性全解

    Android Layout 布局属性全解写的挺全 mark 一下 Android nbsp Layout 布局属性全解 Android 有基本 Layout FrameLayout LinearLayout TableLayout RelativeLayo AbsoluteLayo android 开发者谷歌文档 http android xsoftlab net reference android view ViewGrou

    2026年3月26日
    1
  • 设计模式之工厂模式_单例模式和工厂模式

    设计模式之工厂模式_单例模式和工厂模式概述工厂模式(FactoryPattern)属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象

    2022年8月16日
    9

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号