如何按升序排序IP地址

有什么方法可以对此进行排序吗? 或者我只是需要拆分并使用循环进行比较? 输入

123.4.245.23 104.244.253.29 1.198.3.93 32.183.93.40 104.30.244.2 104.244.4.1 

产量

 1.198.3.93 32.183.93.40 104.30.244.2 104.244.4.1 104.244.253.29 123.4.245.23 

到目前为止,我使用HashMap存储我的数据。 我想按升序对IP地址进行排序。 貌似TreeMap是更好的选择吗?

TLDR

您可以直接跳转到有效的比较方法(参见下面的编辑部分)或
继续你的阅读


为了对IP进行排序,首先需要了解它们。 有两种类型的IP; 32 Bit128 Bit

32位

32位

  • 32 bit IP分为4组0255之间的数字。 这些群体通过一个分开.
  • 如上所示,单个组是8位数据。 这就是组中数字限制在0255之间的原因。
  • 要正确格式化32 bit IP ,应该是int.int.int.int 。 即使int为0也必须在IP地址中显示。 这与128 bit IP不同,可以省略0 s。 例如::5:0:0:5:0:0:0:0:0

128位

128位

  • 128 bit IP分为8组0FFFF之间的数字(相当于65535 )。 与32 bit IPs组不同,这些组是分开购买的:
  • 如上所示,单个组是16位数据。 这就是组中数字限制在0FFFF之间的原因。
  • 要正确格式化128 bit IP您必须遵循几个规则。 可以从组中省略0s,如果剩余的组都是0则也可以省略这些组。 这些团体必须由以下部分分开: 。 如果省略组,则不是0的最后一个组必须后跟: 。 这些规则给我们留下了格式int:int:int:int:int:int:int:int0 s和被省略的组的例子是58f:::fff:2: . 这与58f:0:0:fff:2:0:0:0

排序

一旦IP被分类到它们各自的组中,它们就可以被分类。 要对IP进行排序,您需要使用称为加权的方法。 这是因为简单地将不同的组添加或相乘可能不起作用。 例如,取这两个IP; 192.5.48.198198.48.5.192 。 如果将组的值相加或相乘,则会得到相同的答案。 所以没有办法使用加法和乘法来准确地比较它们。 如果你使用加权,你会得到这样的东西。

32位加权

 Value of IP = (Group one value * 256^4) + (Group two value * 256^3) + (Group three value * 256^2) + (Group four value * 256) 

128位加权

 Value of IP = (Group one value * 65536^8) + (Group two value * 65536^7) + (Group three value * 65536^6) + (Group four value * 65536^5) + (Group five value * 65536^4) + (Group six value * 65536^3) + (Group seven value * 65536^2) + (Group eight value * 65536) 

Java中的代码

只要IP格式合理正确,此代码将分离两种IP然后对它们进行排序。

 import java.util.*; import java.math.*; //For BigInteger import java.util.regex.*; import java.lang.*; public class IPSort { String[] tests = {":8:","::::5:6::8","::::5:6::7","::::5:6::8","123..245.23","1...","..1.","123...23",".1..","123..245.23", "123..245.23", "104.244.253.29", "1.198.3.93", "32.183.93.40", "32.183.93.40", "104.30.244.2", "104.244.4.1","0.0.0.1",":a:","::5:3:4:5:6:78","1::2:3","1::2:3:4","1::5:256.2.3.4","1:1:3000.30.30.30","ae80::217:f2ff:254:7:237:98"}; ArrayList bit32 = new ArrayList(); ArrayList bit128 = new ArrayList(); ArrayList cleanBit32 = new ArrayList(); ArrayList cleanBit128 = new ArrayList(); boolean myMatcher32Bit(String s) { Pattern patter32Bit = Pattern.compile("^(?=(?:[^.]*\\.){3}[^.]*$)(?=(?:[^:]*:){0}[^:]*$)(?=(?:[^a-zA-Z]*[^a-zA-Z])*$)"); Matcher matcher32Bit = patter32Bit.matcher(s); return matcher32Bit.find(); } boolean myMatcher128Bit(String s) { Pattern patter128Bit = Pattern.compile("^(?=(?:[^.]*\\.){0}[^.]*$)(?=(?:[^:]*:){1,7}[^:]*$)"); Matcher matcher128Bit = patter128Bit.matcher(s); return matcher128Bit.find(); } public void sortIntoRespectiveIPTypes() { for(String s: tests) { if(myMatcher32Bit(s)) { bit32.add(s); } else if(myMatcher128Bit(s)) { bit128.add(s); } } System.out.println("32 bit IPs"); for(String ip: bit32) { System.out.println(" "+ip); } System.out.println("\n128 bit IPs"); for(String ip: bit128) { System.out.println(" "+ip); } int count = 0; for(String ip: tests) { if(myMatcher32Bit(ip)==false && myMatcher128Bit(ip)==false) { count++; } } if(count != 0) { System.out.println("\nDidn't match an IP format"); for(String ip: tests) { if(myMatcher32Bit(ip)==false && myMatcher128Bit(ip)==false) { System.out.println(" "+ip); } } } } public void sort32BitIPs(ArrayList bit32, ArrayList newBit32) { ArrayList bigInt32Bit = new ArrayList(); for(String ip:bit32) { String[] tempArray = ip.split("\\."); int i=0; for(String s:tempArray) { if(s.equals("")) { tempArray[i]="0"; } i++; } bigInt32Bit.add(convert32Bit(tempArray)); } Collections.sort(bigInt32Bit); ArrayList fixFormat = new ArrayList(); for(String ip:bit32) { String[] fixArray = ip.split("\\."); int i=0; for(String s:fixArray) { if(s.equals("")) { fixArray[i]="0"; } i++; } StringBuilder strBuilder = new StringBuilder(); for(int i2 = 0; i2 < 4; i2++) { if(i2<3) { try { if(!fixArray[i2].equals("")) { strBuilder.append(fixArray[i2]+"."); } else { strBuilder.append("."); } } catch(Exception e) { strBuilder.append("0."); } } else { try { strBuilder.append(fixArray[i2]); } catch(Exception e) { strBuilder.append("0"); } } } String newString = strBuilder.toString(); fixFormat.add(newString); bit32=fixFormat; } for(BigInteger finalValue:bigInt32Bit) { for(String ip:bit32) { String[] tempArray = ip.split("\\."); int i=0; for(String s:tempArray) { if(s.equals("")) { tempArray[i]="0"; } i++; } if(finalValue.equals(convert32Bit(tempArray))) { if(!newBit32.contains(ip)) { String str = bit32.toString(); String findStr = ip; int lastIndex = 0; int count = 0; while(lastIndex != -1){ lastIndex = str.indexOf(findStr,lastIndex); if(lastIndex != -1){ count++; lastIndex += findStr.length(); } } for(int k = 0; k tempBigIntList = new ArrayList(); int i = 0; for(String s:array) { int power = 4-i; tempArray[i]= Integer.parseInt(s); String string = Integer.toString(tempArray[i]); BigInteger myBigInt = new BigInteger(string); BigInteger num2 = myBigInt.multiply(new BigInteger("256").pow(power)); tempBigIntList.add(num2); i++; } BigInteger bigInt32Bit = new BigInteger("0"); for(BigInteger bI:tempBigIntList) { bigInt32Bit = bigInt32Bit.add(bI); } return bigInt32Bit; } public void sort128BitIPs(ArrayList bit128,ArrayList newBit128) { ArrayList bigInt128Bit = new ArrayList(); for(String ip:bit128) { String[] tempArray = ip.split(":"); int i=0; for(String s:tempArray) { if(s.equals("")) { tempArray[i]="0"; } i++; } bigInt128Bit.add(convert128Bit(tempArray)); } Collections.sort(bigInt128Bit); for(BigInteger finalValue:bigInt128Bit) { for(String ip:bit128) { String[] tempArray = ip.split(":"); int i=0; for(String s:tempArray) { if(s.equals("")) { tempArray[i]="0"; } i++; } if(finalValue.equals(convert128Bit(tempArray))) { if(!newBit128.contains(ip)) { String str = bit128.toString(); String findStr = ip; int lastIndex = 0; int count = 0; while(lastIndex != -1){ lastIndex = str.indexOf(findStr,lastIndex); if(lastIndex != -1){ count++; lastIndex += findStr.length(); } } for(int k = 0; k tempBigIntList = new ArrayList(); int i = 0; for(String s:array) { int power = 8-i; tempArray[i]= Integer.parseInt(s,16); String string = Integer.toString(tempArray[i]); BigInteger myBigInt = new BigInteger(string); BigInteger num2 = myBigInt.multiply(new BigInteger("65536").pow(power)); tempBigIntList.add(num2); i++; } BigInteger bigInt128Bit = new BigInteger("0"); for(BigInteger bI:tempBigIntList) { bigInt128Bit = bigInt128Bit.add(bI); } return bigInt128Bit; } public void printInOrder(ArrayList bit32,ArrayList bit128) { System.out.println("\nSorted IPs"); System.out.println("Sorted 32 bit IPs - Ascending"); for(String ip: bit32) { System.out.println(" "+ip); } Collections.reverse(bit32); System.out.println("\nSorted 32 bit IPs - Descending"); for(String ip: bit32) { System.out.println(" "+ip); } System.out.println("\nSorted 128 bit IPs - Ascending"); for(String ip: bit128) { System.out.println(" "+ip); } Collections.reverse(bit128); System.out.println("\nSorted 128 bit IPs - Descending"); for(String ip: bit128) { System.out.println(" "+ip); } } public void run(ArrayList bit32,ArrayList bit128,ArrayList newBit32,ArrayList newBit128) { sortIntoRespectiveIPTypes(); sort32BitIPs(bit32,newBit32); sort128BitIPs(bit128,newBit128); printInOrder(newBit32,newBit128); } public static void main(String[] args) { IPSort ipS = new IPSort(); ipS.run(ipS.bit32,ipS.bit128,ipS.cleanBit32,ipS.cleanBit128); } } 

作为注释,可以使用此类对IP进行排序,但我的代码不使用它

此代码还将列表按升序排序,然后按降序排序。 运行代码时,将在命令控制台中打印出来

产量

产量

编辑

更有效和准确的方法是使用上面提到的InetAddress类 。 致信200_success代码。

 import java.net.InetAddress; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.UnknownHostException; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Optional; import java.util.stream.Stream; public class IPSort { private static String[] TESTS = {"0:0:0:0:0:0:fff:ffff","::FFFF:222.1.41.90",":8:","::::5:6::8","::::5:6::7","::::5:6::8","123..245.23","1...","..1.","123...23",".1..","123..245.23", "123..245.23", "104.244.253.29", "1.198.3.93", "32.183.93.40", "32.183.93.40", "104.30.244.2", "104.244.4.1","0.0.0.1",":a:","::5:3:4:5:6:78","1::2:3","1::2:3:4","1::5:256.2.3.4","1:1:3000.30.30.30","ae80::217:f2ff:254:7:237:98","::2:3:4:5:6:7","2:3:4:5:6:7","::5:3:4:5:6:7:8","::5:3:4:5:6:7:8:9:0","1::8","1::2:3","1::2:3:4","1::5:256.2.3.4","1:1:3000.30.30.30","ae80::217:f2ff:254.7.237.98","1:2:3:4::5:1.2.3.4","2001:0000:1234:0000:0000:C1C0:ABCD:0876","12345::6:7:8","1::1.2.900.4","fe80::","::ffff:0:0"}; public static class InetAddressComparator implements Comparator { @Override public int compare(InetAddress a, InetAddress b) { byte[] aOctets = a.getAddress(), bOctets = b.getAddress(); int len = Math.max(aOctets.length, bOctets.length); for (int i = 0; i < len; i++) { byte aOctet = (i >= len - aOctets.length) ? aOctets[i - (len - aOctets.length)] : 0; byte bOctet = (i >= len - bOctets.length) ? bOctets[i - (len - bOctets.length)] : 0; if (aOctet != bOctet) return (0xff & aOctet) - (0xff & bOctet); } return 0; } } public static Optional toInetAddress(String s) { try { return Optional.of(InetAddress.getByName(s)); } catch (UnknownHostException badAddress) { return Optional.empty(); } } public static void main(String[] args) throws Exception { System.out.println("Valid 32-bit addresses"); Arrays.stream(TESTS) .map(IPSort::toInetAddress) .filter(Optional::isPresent) .map(Optional::get) .filter((addr) -> addr instanceof Inet4Address) .map(InetAddress::getHostAddress) .forEach(System.out::println); System.out.println("\nValid 128-bit addresses"); Arrays.stream(TESTS) .map(IPSort::toInetAddress) .filter(Optional::isPresent) .map(Optional::get) .filter((addr) -> addr instanceof Inet6Address) .map(InetAddress::getHostAddress) .forEach(System.out::println); System.out.println("\nInvalid addresses"); Arrays.stream(TESTS) .filter((s) -> !toInetAddress(s).isPresent()) .forEach(System.out::println); System.out.println("\nSorted addresses"); Arrays.stream(TESTS) .map(IPSort::toInetAddress) .filter(Optional::isPresent) .map(Optional::get) .sorted(new InetAddressComparator()) .map(InetAddress::getHostAddress) .forEach(System.out::println); } } 

我建议你实现自己的比较器。 请参阅以下文章: 用Java排序IP地址

仅为您复制粘贴:

 /** * LGPL */ public class InetAddressComparator implements Comparator { @Override public int compare(InetAddress adr1, InetAddress adr2) { byte[] ba1 = adr1.getAddress(); byte[] ba2 = adr2.getAddress(); // general ordering: ipv4 before ipv6 if(ba1.length < ba2.length) return -1; if(ba1.length > ba2.length) return 1; // we have 2 ips of the same type, so we have to compare each byte for(int i = 0; i < ba1.length; i++) { int b1 = unsignedByteToInt(ba1[i]); int b2 = unsignedByteToInt(ba2[i]); if(b1 == b2) continue; if(b1 < b2) return -1; else return 1; } return 0; } private int unsignedByteToInt(byte b) { return (int) b & 0xFF; } } 

IP每个片段填充到长度3 ,然后sort如下:

  List ipList = new ArrayList(); ipList.add("123.4.245.23"); ipList.add("104.244.253.29"); ipList.add("1.198.3.93"); ipList.add("32.183.93.40"); ipList.add("104.30.244.2"); ipList.add("104.244.4.1"); Collections.sort(ipList, new Comparator() { @Override public int compare(String o1, String o2) { String[] ips1 = o1.split("\\."); String updatedIp1 = String.format("%3s.%3s.%3s.%3s", ips1[0],ips1[1],ips1[2],ips1[3]); String[] ips2 = o2.split("\\."); String updatedIp2 = String.format("%3s.%3s.%3s.%3s", ips2[0],ips2[1],ips2[2],ips2[3]); return updatedIp1.compareTo(updatedIp2); } }); //print the sorted IP for(String ip: ipList){ System.out.println(ip); } 

它打印:

1.198.3.93
32.183.93.40
104.30.244.2
104.244.4.1
104.244.253.29
123.4.245.23

对于ip4地址,你表明你只需要拆分它。 然后我会将它转换为长值,并按此排序。

 long value = f3 + f2*256 + f1 * 256^2 + f0 * 256^3 

其中f0 – f3是分割值。

 public class IpSort { public static void main(String[] args) { // TODO Auto-generated method stub String[] arr = {"192.168.1.1", "191.122.123.112", "192.161.1.1", "191.122.123.1", "123.24.5.78", "121.24.5.78", "123.24.4.78", "123.2.5.78", "192.1.1.1", "125.45.67.89", "1.1.1.1", "3.4.5.6", "2.2.2.2", "6.6.6.7", "155.155.23.0"}; String tmp; for(int i=0;i Integer.parseInt(instr2[0])) { tmp=arr[j-1]; arr[j-1]=arr[j]; arr[j]=tmp; }else if(Integer.parseInt(instr1[0]) == Integer.parseInt(instr2[0]) && Integer.parseInt(instr1[1]) > Integer.parseInt(instr2[1]) ) { tmp=arr[j-1]; arr[j-1]=arr[j]; arr[j]=tmp; } else if(Integer.parseInt(instr1[0]) == Integer.parseInt(instr2[0]) && Integer.parseInt(instr1[1]) == Integer.parseInt(instr2[1]) && Integer.parseInt(instr1[2]) > Integer.parseInt(instr2[2]) ) { tmp=arr[j-1]; arr[j-1]=arr[j]; arr[j]=tmp; } else if(Integer.parseInt(instr1[0]) == Integer.parseInt(instr2[0]) && Integer.parseInt(instr1[1]) == Integer.parseInt(instr2[1]) && Integer.parseInt(instr1[2]) == Integer.parseInt(instr2[2]) && Integer.parseInt(instr1[3]) > Integer.parseInt(instr2[3]) ) { tmp=arr[j-1]; arr[j-1]=arr[j]; arr[j]=tmp; } } } System.out.println("final sorted list of ips :\n"); for(int k=0;k 

这个简单的逻辑怎么样:

地址:[10.1.1.2,10.22.33.11,10.12.23.12]

1)填写IP以完成12位数字格式,前缀为0:如[010.001.001.002,010.022.033.011,010.012.023,012]

2)删除“。”以使其成为完整的数字串:[010001001002,010022033011,010012023012]

3)申请排序[010001001002,010012023012,010022033011]

4)每3位数后保留点数:[010.001.001.002,010.012.023.012,010.022.033.011]

5)删除前缀0的[10.1.1.2,10.12.23.12,10.22.33.11]

6)排序!

 public class SortIP { public static String getFormattedIP(String ip) { String arg[] = new String[4]; arg = (ip).split("\\."); int i=0; while(i<=3) { if(arg[i].length()==1) { arg[i]="00"+arg[i]; } else if(arg[i].length()==2) { arg[i]="0"+arg[i]; } i++; } return arg[0]+arg[1]+arg[2]+arg[3]; } public static ArrayList sortedList(Object[] obj,String order) { if(order.equalsIgnoreCase("Ascending")) { Arrays.sort(obj, new Comparator() { public int compare(Object o1, Object o2) { return ((Map.Entry) o1).getValue() .compareTo(((Map.Entry) o2).getValue()); } }); } else { Arrays.sort(obj, new Comparator() { public int compare(Object o1, Object o2) { return ((Map.Entry) o2).getValue() .compareTo(((Map.Entry) o1).getValue()); } }); } int counter=0; ArrayList key = new ArrayList(); //int key[] = new int[ipRange.size()]; for (Object e : obj) { key.add(((Map.Entry) e).getKey()); //key[counter++]=((Map.Entry) e).getKey(); System.out.println(((Map.Entry) e).getKey() + " : " + ((Map.Entry) e).getValue()); } return key; } public static void main(String[] args) { Map ipRange= new TreeMap(); Map formatedIpRange= new TreeMap(); ipRange.put(1, "10.1.4.100"); ipRange.put(2, "1.10.400.10"); ipRange.put(3, "196.0.14.15"); ipRange.put(4, "196.70.5.1"); ipRange.put(5, "196.70.7.3"); ipRange.put(6, "153.70.7.0"); for(int j=1;j<=ipRange.size();j++) { formatedIpRange.put(j, Long.parseLong(getFormattedIP(ipRange.get(j)))); } Object[] a = formatedIpRange.entrySet().toArray(); ArrayList key = sortedList(a,"descending"); System.out.println("ordered list "); for (Integer integer : key) { System.out.println(ipRange.get(integer)); } } } 

在Java8中

 import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.AbstractMap; import java.util.Arrays; import java.util.Comparator; import java.util.Map; class Test { private static final Comparator COMPARATOR = Comparator .comparing(InetAddress::getAddress, Comparator.comparingInt((byte[] b) -> b.length) .thenComparing(b -> new BigInteger(1, b))); public static void main(String[] args) { final String[] addresses = { "123.4.245.23", "104.244.253.29", "1.198.3.93", "32.183.93.40", "104.30.244.2", "104.244.4.1" }; for (final String address : sort(addresses)) { System.out.println(address); } } public static String[] sort(final String[] addresses) { return Arrays.stream(addresses) .map(s -> new AbstractMap.SimpleImmutableEntry<>(toInetAddress(s), s)) .sorted(Comparator.comparing(Map.Entry::getKey, Comparator.nullsLast(COMPARATOR))) .map(Map.Entry::getValue) .toArray(String[]::new); } private static InetAddress toInetAddress(final String address) { try { return InetAddress.getByName(address); } catch (final UnknownHostException | SecurityException e) { e.printStackTrace(); return null; } } } 

输出:

 1.198.3.93
 32.183.93.40
 104.30.244.2
 104.244.4.1
 104.244.253.29
 123.4.245.23