1、Java数据类型
1、基本数据类型的变量:
/** * 1、基本数据类型的变量: * * 1)、整数类型:byte(1字节=8bit),short(2字节),int(4字节),long(8字节) * * 2)、浮点数类型:float(4字节),double(8字节) * * 3)、字符类型:char(2字节)----Unicode码 * * 4)、布尔类型:boolean(未指定字节数)----true和false * * 2、引用数据类型的变量: * * 除了基本类型(primitive type)和枚举类型(enumeration type),剩下的都是引用类型,比如String。 * */
(1)、Demo01: 数据取值范围的注意:
//静态方法不需要实例化 public static void basicDataDemo(){ /** * 1、声明long型变量,必须以"l"或"L"结尾,其整数默认是int类型(易超出其取值范围而报错) * 2、需注意数据的取值范围 * (1)、byte的取值范围:-128~127(-2^7~2^7-1) * (2)、short的取值范围:-32768 ~ 32767(-2^15~2^15-1) * (3)、int取值范围:-2147483648 ~ 2147483647(-2^31~2^31-1) * (4)、。。。。。。 * 3、浮点型默认是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型会造成精度损失,因此需要强制类型转换 * 4、整数默认是int类型 */ //错误: //long l = 2147483648; long l = 2147483648L; //byte b=128; byte b=28; //丢失精度,两种解决方案 //float f=1.2; float f1=1.2f; float f2=(float) 1.2; //丢失精度 //short s1 = 1; //s1 = s1 + 1; short s1 = 1; short s2 = 1; s1 = (short)(s1 + 1); //有隐含的强制类型转换,推荐使用 s2 +=1; System.out.println(l); //2147483648 System.out.println(b); //28 System.out.println(f1); //1.2 System.out.println(f2); //1.2 System.out.println(s1); //2 System.out.println(s2); //2 }
(2)、Demo02: String引用数据类型的注意:
/**
* JVM的基本了解:
* 1、方法区内存:存储字节码代码片段、静态变量
* 2、堆内存:new实例变量、数组
* 3、栈内存:局部变量
* */
//静态方法不需要实例化
public static void stringDataDemo(){ /** * 1、String s1 = "123"; * 在静态区的“123”(字符串常量池)创建了一个对象 * 2、String s2 = new String("123"); * 创建了二个对象:一个在静态区的“123”(字符串常量池)对象,一个是用new创建在堆上的对象 * */ String s1 = "123"; String s2 = new String("123"); System.out.println(s1 == s2); //false String s3 = "123456"; String s4 = "123" + "456"; System.out.println(s3 == s4); //true String s5 = s1 + "456"; System.out.println(s5 == s4); //false /** * String与Stringbuffer/ Stringbulider的区别: * * String类型是只读字符串,字符串内容不允许改变 * Stringbuffer/ Stringbulider表示字符串对象可以修改 * 1、 Stringbuffer:有synchronized关键字修饰,表示线程安全的,效率低 * 2、 Stringbulider:无synchronized关键字修饰,表示非线程安全的,效率高 * 开发建议使用:Stringbuffer》Stringbulider》String * */ String a = new String("123"); StringBuffer b = new StringBuffer("123"); b.append("456"); //字符串a不允许修改 System.out.println("a:"+ a); //a:123 System.out.println("b:"+ b); //b:123456 }
2、包装类:
/** * 包装类: * 1、基本包装类 * Boolean * Byte * Short * Character * Long * Integer * Float * Double * * 2、高精度数字 * BigDecimal * BigInteger * */
(1)、Demo03: 数据间转换的注意:
/** * 1、自动类型转换 * byte 、char 、short --> int --> long --> float --> double * * 2、强制类型转换 * 使用强转符:(),可能导致精度损失 * */
//静态方法不需要实例化 public static void dataConversionDemo(){ /** * 数据转换工具类:DataConversionUtil * 1、自动装箱:自动将基本数据类型转换为包装器类型 * 2、自动拆箱:自动将包装器类型转换为基本数据类型 * 3、声明包装类可以避免空指针异常 * */ String a ="123"; int b; int c; //利用包装类实现自动装箱与自动拆箱,即数据类型转换 b = Integer.parseInt(a); //调用工具类的静态方法 c = DataConversionUtil.toInt(a); System.out.println(b); //123 System.out.println(c); //123 int d =123; String e ; String f ; e = DataConversionUtil.toStr(d); f = String.valueOf(d); System.out.println(e); //123 System.out.println(f); //123 //避免空指针异常 Integer i = null; System.out.println(i); //null //报错 //int j = null; //System.out.println(j); }
(2)、数据转换工具类:
DataConversionUtil.class
1)、转换为数组:
/** * 转换为Integer数组<br> * * @param str 被转换的值 * @return 结果 */ public static Integer[] toIntArray(String str) { return toIntArray(",", str); } /** * 转换为Long数组<br> * * @param str 被转换的值 * @return 结果 */ public static Long[] toLongArray(String str) { return toLongArray(",", str); } /** * 转换为Integer数组<br> * * @param split 分隔符 * @param split 被转换的值 * @return 结果 */ public static Integer[] toIntArray(String split, String str) { if (StringUtils.isEmpty(str)) { return new Integer[]{}; } String[] arr = str.split(split); final Integer[] ints = new Integer[arr.length]; for (int i = 0; i < arr.length; i++) { final Integer v = toInt(arr[i], 0); ints[i] = v; } return ints; } /** * 转换为Long数组<br> * * @param split 分隔符 * @param str 被转换的值 * @return 结果 */ public static Long[] toLongArray(String split, String str) { if (StringUtils.isEmpty(str)) { return new Long[]{}; } String[] arr = str.split(split); final Long[] longs = new Long[arr.length]; for (int i = 0; i < arr.length; i++) { final Long v = toLong(arr[i], null); longs[i] = v; } return longs; } /** * 转换为String数组<br> * * @param str 被转换的值 * @return 结果 */ public static String[] toStrArray(String str) { return toStrArray(",", str); } /** * 转换为String数组<br> * * @param split 分隔符 * @param split 被转换的值 * @return 结果 */ public static String[] toStrArray(String split, String str) { return str.split(split); }
2)、转换为Enum对象:
/** * 转换为Enum对象<br> * 如果给定的值为空,或者转换失败,返回默认值<br> * * @param clazz Enum的Class * @param value 值 * @param defaultValue 默认值 * @return Enum */ public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value, E defaultValue) { if (value == null) { return defaultValue; } if (clazz.isAssignableFrom(value.getClass())) { @SuppressWarnings("unchecked") E myE = (E) value; return myE; } final String valueStr = toStr(value, null); if (StringUtils.isEmpty(valueStr)) { return defaultValue; } try { return Enum.valueOf(clazz, valueStr); } catch (Exception e) { return defaultValue; } } /** * 转换为Enum对象<br> * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br> * * @param clazz Enum的Class * @param value 值 * @return Enum */ public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value) { return toEnum(clazz, value, null); }
3)、转换为BigInteger:
/** * 转换为BigInteger<br> * 如果给定的值为空,或者转换失败,返回默认值<br> * 转换失败不会报错 * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 */ public static BigInteger toBigInteger(Object value, BigInteger defaultValue) { if (value == null) { return defaultValue; } if (value instanceof BigInteger) { return (BigInteger) value; } if (value instanceof Long) { return BigInteger.valueOf((Long) value); } final String valueStr = toStr(value, null); if (StringUtils.isEmpty(valueStr)) { return defaultValue; } try { return new BigInteger(valueStr); } catch (Exception e) { return defaultValue; } } /** * 转换为BigInteger<br> * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br> * 转换失败不会报错 * * @param value 被转换的值 * @return 结果 */ public static BigInteger toBigInteger(Object value) { return toBigInteger(value, null); }
4)、转换为BigDecimal:
/** * 转换为BigDecimal<br> * 如果给定的值为空,或者转换失败,返回默认值<br> * 转换失败不会报错 * * @param value 被转换的值 * @param defaultValue 转换错误时的默认值 * @return 结果 */ public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) { if (value == null) { return defaultValue; } if (value instanceof BigDecimal) { return (BigDecimal) value; } if (value instanceof Long) { return new BigDecimal((Long) value); } if (value instanceof Double) { return new BigDecimal((Double) value); } if (value instanceof Integer) { return new BigDecimal((Integer) value); } final String valueStr = toStr(value, null); if (StringUtils.isEmpty(valueStr)) { return defaultValue; } try { return new BigDecimal(valueStr); } catch (Exception e) { return defaultValue; } } /** * 转换为BigDecimal<br> * 如果给定的值为空,或者转换失败,返回默认值<br> * 转换失败不会报错 * * @param value 被转换的值 * @return 结果 */ public static BigDecimal toBigDecimal(Object value) { return toBigDecimal(value, null); }
5)、全角半角转换:
/** * 半角转全角 * * @param input String. * @return 全角字符串. */ public static String toSBC(String input) { return toSBC(input, null); } /** * 半角转全角 * * @param input String * @param notConvertSet 不替换的字符集合 * @return 全角字符串. */ public static String toSBC(String input, Set<Character> notConvertSet) { char c[] = input.toCharArray(); for (int i = 0; i < c.length; i++) { if (null != notConvertSet && notConvertSet.contains(c[i])) { // 跳过不替换的字符 continue; } if (c[i] == ' ') { c[i] = '\u3000'; } else if (c[i] < '\177') { c[i] = (char) (c[i] + 65248); } } return new String(c); } /** * 全角转半角 * * @param input String. * @return 半角字符串 */ public static String toDBC(String input) { return toDBC(input, null); } /** * 替换全角为半角 * * @param text 文本 * @param notConvertSet 不替换的字符集合 * @return 替换后的字符 */ public static String toDBC(String text, Set<Character> notConvertSet) { char c[] = text.toCharArray(); for (int i = 0; i < c.length; i++) { if (null != notConvertSet && notConvertSet.contains(c[i])) { // 跳过不替换的字符 continue; } if (c[i] == '\u3000') { c[i] = ' '; } else if (c[i] > '\uFF00' && c[i] < '\uFF5F') { c[i] = (char) (c[i] - 65248); } } String returnString = new String(c); return returnString; }
6)、数字金额大写转换:
/** * 数字金额大写转换 先写个完整的然后将如零拾替换成零 * * @param n 数字 * @return 中文大写数字 */ public static String digitUppercase(double n) { String[] fraction = {"角", "分"}; String[] digit = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"}; String[][] unit = {{"元", "万", "亿"}, {"", "拾", "佰", "仟"}}; String head = n < 0 ? "负" : ""; n = Math.abs(n); String s = ""; for (int i = 0; i < fraction.length; i++) { s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", ""); } if (s.length() < 1) { s = "整"; } int integerPart = (int) Math.floor(n); for (int i = 0; i < unit[0].length && integerPart > 0; i++) { String p = ""; for (int j = 0; j < unit[1].length && n > 0; j++) { p = digit[integerPart % 10] + unit[1][j] + p; integerPart = integerPart / 10; } s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s; } return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整"); }
3、日期类:
(1)、取得当前年、月、日:
/** * 取得当前年的年份 * * @return int */ public static int getYear() { Calendar calendar = Calendar.getInstance(); return calendar.get(Calendar.YEAR); } /** * 取得当前月的月份 * * @return int */ public static int getMonth() { Calendar calendar = Calendar.getInstance(); return calendar.get(Calendar.MONTH); } /** * 取得当前日的日期 * * @return int */ public static int getDay() { Calendar calendar = Calendar.getInstance(); return calendar.get(Calendar.DATE); }
(2)、格式化时间,时间转字符串:
/** * 格式化时间,时间转字符串 * * @param date null则为当前系统时间 * @param format 格式,null则默认为:'yyyy-MM-dd HH:mm:ss' * @return 字符串格式的日期 */ public static String getDateTimeByStr(Date date, String format) { if (date == null) { date = new Date(); } if (format == null) { format = "yyyy-MM-dd HH:mm:ss"; } return new SimpleDateFormat(format).format(date); }
(3)、获取两时间相隔月份:
/** * 两时间相隔月份 * @param startDate * @param endDate * @return */ public static Integer getDiffMonth(Date startDate, Date endDate){ Calendar start = Calendar.getInstance(); Calendar end = Calendar.getInstance(); start.setTime(startDate); end.setTime(endDate); int result = end.get(Calendar.MONTH) - start.get(Calendar.MONTH); int month = (end.get(Calendar.YEAR) - start.get(Calendar.YEAR)) * 12; return Math.abs(month + result); }
(4)、获得特定日期之后的固定天数的某一天:
/** * @param date 传入的日期 * @param days 要增加的天数 * @return Date 获取的目标日期 * * 获得特定日期之后的固定天数的某一天 */ public static Date addDays(Date date, int days) { Date date1 = null; try { if (null == date) { return date1; } Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.DATE, days); date1 = calendar.getTime(); } catch (Exception e) { e.printStackTrace(); } finally { return date1; } }
(5)、获得特定日期之前的固定天数的某一天:
/** * @param date 传入的日期 * @param days 要回退的天数 * @return Date 获取的目标日期 * * 获得特定日期之前的固定天数的某一天 */ public static Date getPastDate(Date date, int days) { Date date1 = null; try { if (null == date) { return date1; } Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - days); date1 = calendar.getTime(); } catch (Exception e) { e.printStackTrace(); } finally { return date1; } }
/** * 获得特定日期之前的固定天数的某一天的开始时间 * * @param date 传入的日期 * @param days 要回退的天数 * @return Date 获取的目标日期 * */ public static String getStartOfDay(Date date, int days) { Date startDate = null; try { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - days); calendar.getTime(); LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(calendar.getTime().getTime()), ZoneId.systemDefault()); LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN); startDate = Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()); } catch (Exception e) { e.printStackTrace(); }finally { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startDate); } } /** * 获得特定日期之前的固定天数的某一天的结束时间 * * @param date 传入的日期 * @param days 要回退的天数 * @return Date 获取的目标日期 * */ public static String getEndOfDay(Date date, int days) { Date endDate = null; try { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - days); calendar.getTime(); LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(calendar.getTime().getTime()), ZoneId.systemDefault()); LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX); endDate = Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant()); } catch (Exception e) { e.printStackTrace(); }finally { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(endDate); } }
(6)、获取日期相减后的天数:
/** * @param minuendDate 被减数日期 * @param subDate 减数日期 * @return int 相差的天数 * * 获得日期相减后的天数 */ public static int subDate(Date minuendDate, Date subDate) { if (minuendDate != null && subDate != null) { long timeMillions = (minuendDate.getTime() - subDate.getTime()) % (24 * 60 * 60 * 1000); int days = new Long((minuendDate.getTime() - subDate.getTime()) / (24 * 60 * 60 * 1000)).intValue(); if (timeMillions == 0) { return days; } else { return days + 1; } } else { return 0; } }
(7)、获取昨天凌晨后第i刻的时间:
/** * 获取昨天凌晨后第i刻的时间 * @return Date * */ private static Date getYesterdayQuarter(int i) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); calendar.add(Calendar.DATE, -1); //得到前一天 calendar.add(Calendar.MINUTE, i * 15); Date date = calendar.getTime(); return date; }
(8)、获取当前时间对应的昨天第i刻时间:
/** * 获取当前时间对应的昨天第i刻时间 * @return Date * */ private static Date getYesterdayDate(int i) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); calendar.add(Calendar.DATE, -1); //得到前一天 calendar.add(Calendar.MINUTE, i * 15); Date date = calendar.getTime(); return date; }
(9)、获取今天凌晨后第i刻的时间:
/** * 获取今天凌晨后第i刻的时间 * @return Date * */ private static Date getNowQuarter(int i) { DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); calendar.add(Calendar.MINUTE, i * 15); Date date = calendar.getTime(); return date; }
(10)、计算两时间相差的分钟数:
/** * 计算两时间相差的分钟数 * @return long * */ private static long getDifferenceMinute(Date startDate, Date endDate) { long between = (endDate.getTime() - startDate .getTime())/1000; long min = between/60; return min; }
4、网络工具类:
(1)、根据CIDR返回IPV6网络地址信息:
(2)、获取IPV6地址的二进制分段数据:
(3)、获取IPV6地址的十进制数据:
(4)、根据CIDR返回IPV6网络起始/结束地址信息的十进制数组:
(5)、将IPV6网络十进制整数形式转换为字符串形式(最简IPV6地址格式):
(6)、校验IPV6是否合法:
(7)、获取全格式IPV6地址信息:
(8)、获取最简格式IPV6地址信息:
(9)、校验IPV6地址是否在某网段掩码中:
(10)、返回从给定的IPV6地址后的所有规划的IPV6地址信息:
工具类:
import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import java.math.BigDecimal; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.text.Normalizer; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @Slf4j public class IPManageUtils { /** * 根据CIDR返回IPV6网络地址信息 * * @Param cidr: 例:"1101:6723:5B06:0001:0000:0004:2000:2F00/119" */ public static List<String> getIpv6ListByCidr(String cidr) { List<String> list = new ArrayList<>(); try { BigInteger[] ipv6Integer = getIpv6StartAndEndByCidr(cidr); BigInteger ipv6IntegerStart = ipv6Integer[0]; BigInteger ipv6IntegerEnd = ipv6Integer[1]; while (true) { String ip = int10Toipv6(ipv6IntegerStart); list.add(ip); //+1操作 ipv6IntegerStart = ipv6IntegerStart.add(BigInteger.ONE); if (ipv6IntegerStart.compareTo(ipv6IntegerEnd) == 1) { break; } } return list; } catch (Exception e){ log.error("CIDR:{}格式错误", cidr); return list; } } /** * 获取IPV6地址的二进制分段数据(返回-1说明给定的ipv6不合法) * * @return: 十六进制转二进制 * @throws UnknownHostException */ public static String subsectionIpv6To2(String ipv6) throws UnknownHostException { if (isValidIpv6Addr(ipv6)) { ipv6 = completIpv6(ipv6); String[] split = ipv6.split(":"); String tmpString = ""; if (split.length == 8) { for (int i = 0; i < split.length; i++) { String str = Long.toBinaryString(Long.valueOf(split[i], 16)); tmpString += str + ":"; } } return tmpString.substring(0, tmpString.length() - 1); } return "-1"; } /** * 获取IPV6地址的10进制数据 * * @return */ public static BigInteger ipv6ToBytesToBigInteger(String ipv6) { byte[] ret = new byte[17]; ret[0] = 0; int ib = 16; boolean comFlag = false;// ipv4混合模式标记 if (ipv6.startsWith(":"))// 去掉开头的冒号 ipv6 = ipv6.substring(1); if (ipv6.endsWith("::")) { ipv6 = ipv6+"0"; } 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 new BigInteger(ret); } /** * 根据CIDR返回IPV6网络起始/结束地址信息的十进制数组 * * @return */ public static BigInteger[] getIpv6StartAndEndByCidr(String cidr) { try { cidr = cidr.trim(); BigInteger[] info = new BigInteger[2]; // 判断是否是具体IP int index = cidr.indexOf("/"); if (index < 0) { info[0] = ipv6ToBytesToBigInteger(cidr); info[1] = ipv6ToBytesToBigInteger(cidr); if (info[0] == null || info[1] == null) { return null; } return info; } String ipinfo = cidr.substring(0, index); Integer count = Integer.valueOf(cidr.substring(index + 1)); StringBuffer mask = new StringBuffer(); for (int i = 0; i < 128; i++) { if (i<count) { mask.append("1"); }else { mask.append("0"); } } String string = new BigInteger(mask.toString(),2).toString(10); BigInteger areaIp = ipv6ToBytesToBigInteger(ipinfo); info[0] = areaIp.and(new BigInteger(string)); String re = mask.substring(mask.lastIndexOf("1")+1).replace("0", "1"); info[1] = areaIp.or(new BigInteger(new BigInteger(re.toString(),2).toString(10))); if (info[0] == null || info[1] == null) { return null; } return info; } catch (Exception e) { return null; } } /** * 将IPV6网络十进制整数形式转换为字符串形式(最简IPV6地址格式) * @return */ public static String int10Toipv6(BigInteger big) { String str = ""; BigInteger ff = BigInteger.valueOf(0xffff); for (int i = 0; i < 8; i++) { str = big.and(ff).toString(16) + ":" + str; big = big.shiftRight(16); } str = str.substring(0, str.length() - 1); return str.replaceFirst("(^|:)(0+(:|$)){2,8}", "::"); } /** * 校验ipv6是否合法 * * @return */ public static boolean isValidIpv6Addr(String ipAddr) { String regex = "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:)|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}(:[0-9A-Fa-f]{1,4}){1,2})|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4}){1,3})|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){1,4})|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){1,5})|([0-9A-Fa-f]{1,4}:(:[0-9A-Fa-f]{1,4}){1,6})|(:(:[0-9A-Fa-f]{1,4}){1,7})|(([0-9A-Fa-f]{1,4}:){6}(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})|(([0-9A-Fa-f]{1,4}:){5}:(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4}){0,1}:(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}:(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}:(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})|([0-9A-Fa-f]{1,4}:(:[0-9A-Fa-f]{1,4}){0,4}:(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})|(:(:[0-9A-Fa-f]{1,4}){0,5}:(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}))$"; if (ipAddr == null || ipAddr.trim().length() == 0) { return false; } ipAddr = Normalizer.normalize(ipAddr, Normalizer.Form.NFKC); Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(ipAddr); boolean match = matcher.matches(); return match; } /** * * 获取全格式IPV6地址信息(将ipv6每段补齐4位,如果返回-1说明给定的ipv6不合法) * * @return * @throws UnknownHostException */ public static String completIpv6(String ipv6) throws UnknownHostException { StringBuffer str = new StringBuffer(); if (isValidIpv6Addr(ipv6)) { String ip = InetAddress.getByName(ipv6).toString().replace("/", ""); String[] info = ip.split(":"); for (int i = 0; i < info.length; i++) { switch (info[i].length()) { case 1: info[i] = "000" + info[i]; break; case 2: info[i] = "00" + info[i]; break; case 3: info[i] = "0" + info[i]; break; default: break; } if (i < 7) { str.append(info[i] + ":"); } else { str.append(info[i]); } } }else { return "-1"; } return str.toString(); } /** * 获取最简格式IPV6地址信息(将ipv6地址压缩为最简模式 ,如果返回-1说明给定的ipv6不合法) * * IPv6简写规范: * 1)每个IPv6地址段起始的0可以被省略; * 2)如果一段为4个零,可以简写为一个0 * 3)如果有连续的多个段全为0,则可以使用::表示 注:一个地址段中只能有一个::出现,不可以出现两个及以上 */ public static String shortedIpv6(String ipv6) { if (isValidIpv6Addr(ipv6)) { String shortIP=""; String[] arr = ipv6.split(":"); //去掉每组数据前的0 for (int i = 0; i < arr.length; i++){ arr[i] = arr[i].replaceAll("^0{1,3}", ""); } //最长的连续0 String[] arr2 = arr.clone(); for (int i = 0; i < arr2.length; i++){ if (!"0".equals(arr2[i])){ arr2[i] = "-"; } } Pattern pattern = Pattern.compile("0{2,}"); Matcher matcher = pattern.matcher(StringUtils.join(Arrays.asList(arr2), "")); String maxStr= ""; int start = -1; int end = -1; while (matcher.find()) { if(maxStr.length()<matcher.group().length()) { maxStr=matcher.group(); start = matcher.start(); end = matcher.end(); } } // 组合IPv6简写地址 if(maxStr.length()>0) { for (int i = start; i < end; i++){ arr[i] = ":"; } } shortIP = StringUtils.join(Arrays.asList(arr), ":"); shortIP= shortIP.replaceAll(":{2,}", "::"); return shortIP; } return "-1"; } /** * 校验ipv6地址是否在某网段掩码中 * * @Param(iparea):参数可以是CIDR,或IPV6地址 * @throws Exception */ public static boolean ipv6IsInRange(String ipv6, String iparea) throws Exception { int suffix = 0; if (iparea.contains("/")) { suffix = Integer.parseInt(iparea.substring(iparea.indexOf("/") + 1)); iparea = iparea.substring(0, iparea.indexOf("/")); } BigInteger ipv6Big = ipv6ToBytesToBigInteger(ipv6); BigInteger ipv6areaBig = ipv6ToBytesToBigInteger(iparea); BigDecimal ss = new BigDecimal(2); BigDecimal pow = ss.pow(128); BigInteger aa = new BigInteger(pow.toString()); String str = aa.toString(2).replaceAll("0", "1").substring(1); BigInteger bb = new BigInteger(str, 2); String str1 = bb.shiftLeft(128 - suffix).toString(2); String str2 = str1.substring(128 - suffix, str1.length()); BigInteger mask = new BigInteger(str2, 2); return ipv6Big.and(mask).compareTo(ipv6areaBig.and(mask)) == 0 ? true : false; } /** * 返回从给定的ipv6地址后的所有规划的ipv6地址信息 * * @param ipv6Start 给定ipv6开始ip * @param count 规划需要IP数量 * @return * @throws UnknownHostException */ public static List<String> getIpv6List(String ipv6Start , int count) throws UnknownHostException { List<String> list = new ArrayList<>(); if(isValidIpv6Addr(ipv6Start)) { String ipv6 = completIpv6(ipv6Start); BigInteger ipv6IntegerStart = ipv6ToBytesToBigInteger(ipv6); BigInteger cou = new BigInteger(String.valueOf(count-1)); BigInteger ipv6IntegerEnd = ipv6IntegerStart.add(cou); while(true){ String ip = int10Toipv6(ipv6IntegerStart); list.add(ip); //+1操作 ipv6IntegerStart = ipv6IntegerStart.add(BigInteger.ONE); if(ipv6IntegerStart.compareTo(ipv6IntegerEnd)==1) { break; } } } return list; } private static long ipToLong(String strIP) { long[] ip = new long[4]; String[] ipSec = strIP.split("\\."); for (int k = 0; k < 4; k++) { ip[k] = Long.valueOf(ipSec[k]); } return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3]; } private static String longToIp(long ipaddress) { StringBuffer sb = new StringBuffer(""); sb.append(String.valueOf((ipaddress >>> 24))); sb.append("."); sb.append(String.valueOf((ipaddress & 0x00FFFFFF) >>> 16)); sb.append("."); sb.append(String.valueOf((ipaddress & 0x0000FFFF) >>> 8)); sb.append("."); sb.append(String.valueOf((ipaddress & 0x000000FF))); return sb.toString(); } 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) throws Exception { System.out.println(JSONObject.toJSONString(getIpv6ListByCidr("1101:6723:5B06:0001:0000:0000:2000:2F00/119"))); System.out.println(JSONObject.toJSONString(getIpv6ListByCidr("1101:6723:5B06:0001:0000:0000:2000:2F00/119").size())); BigInteger[] a = getIpv6StartAndEndByCidr("1101:6723:5B06:0001:0000:0000:2000:2F00/119"); System.out.println(JSONObject.toJSONString(a)); System.out.println(int10Toipv6(a[0])); System.out.println(int10Toipv6(a[1])); System.out.println(isValidIpv6Addr("1101:6723:5b06:1::2000:2ffd")); System.out.println(completIpv6("1101:6723:5b06:1::2000:2ffd")); System.out.println(shortedIpv6("1101:6723:5b06:0001:0000:0000:2000:2ffd")); System.out.println(ipv6ToBytesToBigInteger("1101:6723:5b06:1::2000:2e00")); System.out.println(ipv6ToBytesToBigInteger("1101:6723:5b06:0001:0000:0000:2000:2e00")); System.out.println(subsectionIpv6To2("1101:6723:5b06:1::2000:2e00")); System.out.println(ipv6IsInRange("1101:6723:5b06:0001:0000:0000:2000:2e00", "1101:6723:5b06:1::2000:2e00")); System.out.println(JSONObject.toJSONString(getIpv6List("1101:6723:5b06:1::2000:2e09", 100))); }