ipv6掩碼格式解析

一:背景:在生產中,咱們會遇到根據ipv6的地址判斷該ipv6屬於哪一個地市。網絡

首先咱們須要拿到全國的ipv6地址分配表。地址分配表通常是用掩碼錶示的。例如app

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 APui

等,lua

如第一行 2001:250:100::/40 就表示 區段內的ip都屬於中國 * * 教育網。orm

二:知識補充:ipv6有三種表示方法,具體能夠百度去ip

1.冒分十六進制表示法格式爲X:X:X:X:X:X:X:Xget

2.0位壓縮表示法,FF01:0:0:0:0:0:0:1101 → FF01::1101input

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.1string

 

三:代碼實現。下面的代碼實現 輸入一個ipv6掩碼,輸出表明的ipv6的開始地址,和結束地址。這樣,拿到用戶的ipv6具體地址後,就能夠判斷是否在開始,結束地址之中,從而判斷所屬地市。it

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

相關文章
相關標籤/搜索