Advertisement
1988coder

751. IP to CIDR

Dec 31st, 2018
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.83 KB | None | 0 0
  1. /**
  2.  * Using Bit Manipulation. This code handles 0.0.0.0 IP address. 0.0.0.0 is a
  3.  * valid IP address. https://en.wikipedia.org/wiki/IPv4#Special-use_addresses
  4.  *
  5.  * Refer:
  6.  * https://leetcode.com/problems/ip-to-cidr/discuss/110222/Very-Simple-Java-Solution-(beat-100)
  7.  *
  8.  * Time Complexity: O(M + N log N) ~= O(N log N)
  9.  *
  10.  * O(M) = to convert String IP to decimal number. This can be considered
  11.  * constant since the length of IP cannot be less than 4 and more than 15. Code
  12.  * inside the first while loop takes LOG N time. This can be considered constant
  13.  * since there are max 32 bits in an IP address. This while loop will iterate
  14.  * for multiple times till N IP address are generated. Thus time complexity of
  15.  * this while loop is O(N log N).
  16.  *
  17.  * Space Complexity: O(1)
  18.  *
  19.  * M = Length of IP String. N = Number of IPs required.
  20.  */
  21. class Solution {
  22.     public List<String> ipToCIDR(String ip, int n) {
  23.         List<String> result = new ArrayList();
  24.         if (ip == null || n <= 0) {
  25.             return result;
  26.         }
  27.         if (n == 1) {
  28.             result.add(ip + "/32");
  29.             return result;
  30.         }
  31.  
  32.         // Converting String IP to its decimal number.
  33.         long ipNum = 0;
  34.         for (String o : ip.split("\\.")) {
  35.             ipNum = ipNum * 256 + Long.parseLong(o);
  36.         }
  37.  
  38.         while (n > 0) {
  39.             // This will extract the integer corresponding to the first set bit from right.
  40.             // This will help to get the lenght of the CIDR block. Zero bits after this set
  41.             // bit are changed to create next IP addresses.
  42.             long cidrBlockLen = ipNum & -ipNum;
  43.  
  44.             // This IF condition is required if input IP is 0.0.0.0
  45.             if (cidrBlockLen == 0) {
  46.                 cidrBlockLen = n;
  47.                 int count = 0;
  48.                 while (cidrBlockLen > 0) {
  49.                     cidrBlockLen >>= 1;
  50.                     count++;
  51.                 }
  52.                 cidrBlockLen = 1 << (count - 1);
  53.             }
  54.  
  55.             while (cidrBlockLen > n) {
  56.                 cidrBlockLen /= 2;
  57.             }
  58.  
  59.             result.add(genCidrBlock(ipNum, cidrBlockLen));
  60.  
  61.             // Getting ready for next iteration.
  62.             ipNum += cidrBlockLen;
  63.             n -= cidrBlockLen;
  64.         }
  65.  
  66.         return result;
  67.     }
  68.  
  69.     private String genCidrBlock(long ipNum, long blockLen) {
  70.         // Extracting the octets from the IP address.
  71.         int[] ip = new int[4];
  72.         for (int i = 0; i < 4; i++) {
  73.             ip[i] = (int) ipNum & 255;
  74.             ipNum >>= 8;
  75.         }
  76.  
  77.         // Calculating the common prefix of CIDT block.
  78.         int prefix = 33;
  79.         while (blockLen > 0) {
  80.             prefix--;
  81.             blockLen /= 2;
  82.         }
  83.  
  84.         return ip[3] + "." + ip[2] + "." + ip[1] + "." + ip[0] + "/" + prefix;
  85.     }
  86. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement