zoukankan      html  css  js  c++  java
  • ipv6掩码格式解析

    一:背景:在生产中,我们会遇到根据ipv6的地址判断该ipv6属于哪个地市。

    首先我们需要拿到全国的ipv6地址分配表。地址分配表一般是用掩码表示的。例如

    2001:250:100::/40 中国 中国 * * 教育网 36.894402 104.166000 Asia/Chongqing UTC+8 * 86 CN AP
    2001:250:200::/48 中国 北京 北京 清华大学网络科学与网络空间研究院 教育网 39.904989 116.405285 Asia/Shanghai UTC+8 110000 86 CN AP
    2001:250:201::/48 中国 北京 北京 北京大学 教育网 39.904989 116.405285 Asia/Shanghai UTC+8 110000 86 CN AP

    等,

    如第一行 2001:250:100::/40 就表示 区段内的ip都属于中国 * * 教育网。

    二:知识补充:ipv6有三种表示方法,具体可以百度去

    1.冒分十六进制表示法格式为X:X:X:X:X:X:X:X

    2.0位压缩表示法,FF01:0:0:0:0:0:0:1101 → FF01::1101

    3.内嵌IPv4地址表示法
      为了实现IPv4-IPv6互通,IPv4地址会嵌入IPv6地址中,此时地址常表示为:X:X:X:X:X:X:d.d.d.d,前96b采用冒分十六进制表示,而最后32b地址则使用IPv4的点分十进制表示,例如::192.168.0.1与::FFFF:192.168.0.1

    三:代码实现。下面的代码实现 输入一个ipv6掩码,输出代表的ipv6的开始地址,和结束地址。这样,拿到用户的ipv6具体地址后,就可以判断是否在开始,结束地址之中,从而判断所属地市。

    public class IpV6Format {
    private Map<String, String> hexToBinaryMap;
    private Map<String, String> binaryToHexMap;
    private String ipv6;

    public IpV6Format() {
    hexToBinaryMap = new HashMap<>();
    hexToBinaryMap.put("0", "0000");
    hexToBinaryMap.put("1", "0001");
    hexToBinaryMap.put("2", "0010");
    hexToBinaryMap.put("3", "0011");
    hexToBinaryMap.put("4", "0100");
    hexToBinaryMap.put("5", "0101");
    hexToBinaryMap.put("6", "0110");
    hexToBinaryMap.put("7", "0111");
    hexToBinaryMap.put("8", "1000");
    hexToBinaryMap.put("9", "1001");
    hexToBinaryMap.put("a", "1010");
    hexToBinaryMap.put("b", "1011");
    hexToBinaryMap.put("c", "1100");
    hexToBinaryMap.put("d", "1101");
    hexToBinaryMap.put("e", "1110");
    hexToBinaryMap.put("f", "1111");

    binaryToHexMap = new HashMap<>();
    binaryToHexMap.put("0000", "0");
    binaryToHexMap.put("0001", "1");
    binaryToHexMap.put("0010", "2");
    binaryToHexMap.put("0011", "3");
    binaryToHexMap.put("0100", "4");
    binaryToHexMap.put("0101", "5");
    binaryToHexMap.put("0110", "6");
    binaryToHexMap.put("0111", "7");
    binaryToHexMap.put("1000", "8");
    binaryToHexMap.put("1001", "9");
    binaryToHexMap.put("1010", "a");
    binaryToHexMap.put("1011", "b");
    binaryToHexMap.put("1100", "c");
    binaryToHexMap.put("1101", "d");
    binaryToHexMap.put("1110", "e");
    binaryToHexMap.put("1111", "f");
    }

    private String hexToBinary(String hexString) {
    hexString = hexString.toLowerCase();
    StringBuilder binarySB = new StringBuilder();
    if (hexString.length() == 0) {
    hexString = "0000";
    }
    if (hexString.length() == 1) {
    hexString = "000" + hexString;
    }
    if (hexString.length() == 2) {
    hexString = "00" + hexString;
    }
    if (hexString.length() == 3) {
    hexString = "0" + hexString;
    }
    for (char item : hexString.toCharArray()) {
    binarySB.append(hexToBinaryMap.get(String.valueOf(item)));
    }

    return binarySB.toString();
    }

    public String[] formatIpV6(String ipv6String) {
    String[] ret = new String[2];
    StringBuilder sb = new StringBuilder();
    ipv6="";
    if (ipv6String.contains("/")) {
    //如果带有掩码格式FE80::/64 , 1:123::ABCD:0:1/96
    String groups[] = ipv6String.split("/");
    ipv6 = groups[0];
    int yanMa = Integer.valueOf(groups[1]);
    String ipv6Items[] = ipv6.split(":");
    long toInsertCount = 8 - Arrays.stream(ipv6Items).filter(p -> !p.equals("")).count();
    fillIpv6(sb, ipv6Items, toInsertCount);

    String yanMaString = sb.toString().substring(0, yanMa);
    StringBuilder ipv6StartInBinary = new StringBuilder(yanMaString);
    StringBuilder ipv6EndInBinary = new StringBuilder(yanMaString);
    int fillCount = 128 - Integer.valueOf(yanMaString.length());
    while (fillCount-- > 0) {
    ipv6StartInBinary.append("0");
    ipv6EndInBinary.append("1");
    }
    ret[0] = binaryToHexInIP(ipv6StartInBinary.toString());
    ret[1] = binaryToHexInIP(ipv6EndInBinary.toString());
    }
    return ret;
    }

    private void fillIpv6(StringBuilder sb, String[] ipv6Items, long toInsertCount) {
    for (String item : ipv6Items) {
    if (!item.equals("")) {
    sb.append(hexToBinary(item));
    } else {
    while (toInsertCount-- > 0) {
    sb.append(hexToBinary(item));
    }
    }
    }
    while (toInsertCount-- > 0) {
    sb.append(hexToBinary(""));
    }
    }

    private String binaryToHexInIP(String ipInBinaryString) {
    int ipLength = ipInBinaryString.length();
    int index = 0;
    int partCount = 0;
    StringBuilder ret = new StringBuilder();
    while (index < ipLength) {
    String part = ipInBinaryString.substring(index, index + 4);
    ret.append(binaryToHexMap.get(part));
    partCount++;
    if (partCount % 4 == 0 && partCount != 32) {
    ret.append(":");
    }
    index += 4;
    }
    return ret.toString();
    }

    public static void main(String[] args) {
    IpV6Format format = new IpV6Format();
    // String[] ret1 = format.formatIpV6("2001:250:380B::/48");
    // System.out.println("2001:250:380B::/48 range:" );
    // System.out.println("start ip :" + ret1[0]);
    // System.out.println("end ip :" + ret1[1]);
    //
    // String[] ret2 = format.formatIpV6("2001:256:800::/37");
    // System.out.println("2001:256:800::/37 range:" );
    // System.out.println("start ip :" + ret2[0]);
    // System.out.println("end ip :" + ret2[1]);

    String[] ret3 = format.formatIpV6("2001:256::/40");
    System.out.println("2001:256::/40 range:");
    System.out.println("start ip " + ret3[0]);
    System.out.println("end ip " + ret3[1]);


    // String[] ret4 = format.formatIpV6("::FFFF:192.168.0.1");
    // System.out.println("::FFFF:192.168.0.1 range:" );
    // System.out.println("start ip :" + ret4[0]);
    // System.out.println("end ip :" + ret4[1]);


    }
    }

    下面的代码实现了输入用户的ipv6地址输出标准冒分十六进制表示法,并且补足0。

    public class UDFIPV6Format extends UDF {
    private static Map<String, String> hexToBinaryMap;
    private static Map<String, String> binaryToHexMap;
    private static Map<Integer, String> binaryFillMap;

    public UDFIPV6Format() {
    hexToBinaryMap = new HashMap<>();
    hexToBinaryMap.put("0", "0000");
    hexToBinaryMap.put("1", "0001");
    hexToBinaryMap.put("2", "0010");
    hexToBinaryMap.put("3", "0011");
    hexToBinaryMap.put("4", "0100");
    hexToBinaryMap.put("5", "0101");
    hexToBinaryMap.put("6", "0110");
    hexToBinaryMap.put("7", "0111");
    hexToBinaryMap.put("8", "1000");
    hexToBinaryMap.put("9", "1001");
    hexToBinaryMap.put("a", "1010");
    hexToBinaryMap.put("b", "1011");
    hexToBinaryMap.put("c", "1100");
    hexToBinaryMap.put("d", "1101");
    hexToBinaryMap.put("e", "1110");
    hexToBinaryMap.put("f", "1111");

    binaryToHexMap = new HashMap<>();
    binaryToHexMap.put("0000", "0");
    binaryToHexMap.put("0001", "1");
    binaryToHexMap.put("0010", "2");
    binaryToHexMap.put("0011", "3");
    binaryToHexMap.put("0100", "4");
    binaryToHexMap.put("0101", "5");
    binaryToHexMap.put("0110", "6");
    binaryToHexMap.put("0111", "7");
    binaryToHexMap.put("1000", "8");
    binaryToHexMap.put("1001", "9");
    binaryToHexMap.put("1010", "a");
    binaryToHexMap.put("1011", "b");
    binaryToHexMap.put("1100", "c");
    binaryToHexMap.put("1101", "d");
    binaryToHexMap.put("1110", "e");
    binaryToHexMap.put("1111", "f");

    binaryFillMap = new HashMap<>();
    binaryFillMap.put(1, "0");
    binaryFillMap.put(2, "00");
    binaryFillMap.put(3, "000");
    binaryFillMap.put(4, "0000");
    binaryFillMap.put(5, "00000");
    binaryFillMap.put(6, "000000");
    binaryFillMap.put(7, "0000000");
    }

    /**
    * format ipv6 to standard format
    */
    public String evaluate(Text n) {
    if (n == null || n.toString().trim().equals("")) {
    return null;
    }
    String ipv6String = n.toString();
    StringBuilder sb = new StringBuilder();
    if (ipv6String.contains(".")) {
    //ipv4混合模式
    String ipv6Items[] = ipv6String.split(":");
    int notNullCount = 0;
    for (String item : ipv6Items) {
    if (!item.equals("")) {
    notNullCount++;
    }
    }
    int toInsertCount = 7 - notNullCount;
    fillIpv6(sb, ipv6Items, toInsertCount);
    } else {
    String ipv6Items[] = ipv6String.split(":");
    int notNullCount = 0;
    for (String item : ipv6Items) {
    if (!item.equals("")) {
    notNullCount++;
    }
    }
    int toInsertCount = 8 - notNullCount;
    fillIpv6(sb, ipv6Items, toInsertCount);
    }
    String ipv6InHex = binaryToHexInIP(sb.toString());

    return ipv6InHex;
    }

    private void fillIpv6(StringBuilder sb, String[] ipv6Items, long toInsertCount) {
    for (String item : ipv6Items) {
    if (!item.equals("")) {
    if (item.contains(".")) {
    for (String part : item.split("\.")) {
    sb.append(fillBinary(Integer.toBinaryString(Integer.valueOf(part))));
    }
    } else {
    sb.append(hexToBinary(item));
    }
    } else {
    while (toInsertCount-- > 0) {
    sb.append(hexToBinary(item));
    }
    }
    }

    while (toInsertCount-- > 0) {
    sb.append(hexToBinary(""));
    }
    }

    private String fillBinary(String input) {
    int count = 8 - input.length();
    if (count > 1) {
    return binaryFillMap.get(count) + input;
    } else {
    return input;
    }
    }

    private String hexToBinary(String hexString) {
    hexString = hexString.toLowerCase();
    StringBuilder binarySB = new StringBuilder();
    if (hexString.length() == 0) {
    hexString = "0000";
    }
    if (hexString.length() == 1) {
    hexString = "000" + hexString;
    }
    if (hexString.length() == 2) {
    hexString = "00" + hexString;
    }
    if (hexString.length() == 3) {
    hexString = "0" + hexString;
    }
    for (char item : hexString.toCharArray()) {
    binarySB.append(hexToBinaryMap.get(String.valueOf(item)));
    }

    return binarySB.toString();
    }

    private String binaryToHexInIP(String ipInBinaryString) {
    int ipLength = ipInBinaryString.length();
    int index = 0;
    int partCount = 0;
    StringBuilder ret = new StringBuilder();
    while (index < ipLength) {
    String part = ipInBinaryString.substring(index, index + 4);
    ret.append(binaryToHexMap.get(part));
    partCount++;
    if (partCount % 4 == 0 && partCount != 32) {
    ret.append(":");
    }
    index += 4;
    }
    return ret.toString();
    }


    public static void main(String[] args) {
    //BigInteger ret = StringToBigInt("2001:256:101:2001:256:101:2001:256");
    //System.out.println(ret);
    UDFIPV6Format format = new UDFIPV6Format();
    String ret1 = format.evaluate(new Text("::192.168.0.1"));
    String ret2 = format.evaluate(new Text("2001:DB8:0:23:8:800:200C:417A"));
    String ret3 = format.evaluate(new Text("2001::800:200C:417A"));
    System.out.println(ret1);
    System.out.println(ret2);
    System.out.println(ret3);
    }
    }

  • 相关阅读:
    POJ 3710 Christmas Game#经典图SG博弈
    POJ 2599 A funny game#树形SG(DFS实现)
    POJ 2425 A Chess Game#树形SG
    LeetCode Array Easy 122. Best Time to Buy and Sell Stock II
    LeetCode Array Easy121. Best Time to Buy and Sell Stock
    LeetCode Array Easy 119. Pascal's Triangle II
    LeetCode Array Easy 118. Pascal's Triangle
    LeetCode Array Easy 88. Merge Sorted Array
    ASP.NET MVC 学习笔记之 MVC + EF中的EO DTO ViewModel
    ASP.NET MVC 学习笔记之面向切面编程与过滤器
  • 原文地址:https://www.cnblogs.com/doosmile/p/10147436.html
Copyright © 2011-2022 走看看