• 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);
    }
    }

  • 相关阅读:
    【Swift后台】环境安装
    【Swift后台】背景介绍
    【Swift后台】目录
    退居三线iOS开发的自主开发历程
    Swift调用微信支付宝SDK(Swift4.0)
    ORACLE取对照表不等的数据
    Binary转换成Hex字符串
    利用OpenSSL创建证书链并应用于IIS7
    sysctl.conf和limit.conf备忘待查
    Use Wireshark to capture loopback traffic without a loopback adapter (转)
  • 原文地址:https://www.cnblogs.com/doosmile/p/10147436.html
Copyright © 2020-2023  润新知