Created
April 8, 2020 02:24
-
-
Save wushbin/2260ddd0a3c21051029036c38298853f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public List<String> ipToCIDR(String ip, long n) { | |
List<String> result = new ArrayList<>(); | |
long ipNum = 0; | |
String[] tokens = ip.split("\\."); | |
for (int i = 0; i < 4; i++) { | |
ipNum = ipNum * 256 + (long) Integer.parseInt(tokens[i]); | |
} | |
if (n + ipNum > 4294967296L) { | |
return result; | |
} else if (n == 4294967296L) { | |
result.add("0.0.0.0/0"); | |
return result; | |
} | |
long cnt = 0; | |
while(cnt < n) { | |
// get rightmost set bit | |
long x = ipNum & -ipNum; | |
if (x == 0) { | |
x = 1; | |
while((x << 1) <= n) { | |
x <<= 1; | |
} | |
} else { | |
while(cnt + x > n) { | |
x >>= 1; | |
} | |
} | |
cnt += x; | |
result.add(toCIDR(ipNum, x)); | |
ipNum += x; | |
} | |
return result; | |
} | |
public String toCIDR(long num, long x) { | |
int cnt = 0; | |
while(x > 0) { | |
x >>= 1; | |
cnt += 1; | |
} | |
int[] ip = new int[4]; | |
for (int i = 3; i >= 0; i--) { | |
ip[i] = (int) num & 255; | |
num >>= 8; | |
} | |
StringBuilder sb = new StringBuilder(); | |
for (int i = 0; i < 4; i++) { | |
sb.append(ip[i]).append("."); | |
} | |
sb.setLength(sb.length() - 1); | |
int preBit = 32 - (cnt - 1); | |
sb.append("/").append(preBit); | |
return sb.toString(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.junit.Test; | |
import java.io.*; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.List; | |
import java.util.Scanner; | |
public class CIDR { | |
class InputValues { | |
String ip; | |
long n; | |
public InputValues(String ip, long n) { | |
this.ip = ip; | |
this.n = n; | |
} | |
@Override | |
public String toString() { | |
return ip + "\t" + n; | |
} | |
} | |
@Test | |
public void test() { | |
System.out.println(0 & -0); | |
} | |
public void generateOutput() throws IOException { | |
File[] files = readFolder("src/input/CIDR"); | |
for (int i = 0; i < files.length; i++) { | |
File file = files[i]; | |
CIDR.InputValues test = readFile(file); | |
List<String> res = ipToCIDR(test.ip, test.n); | |
String outfileName = "src/output/CIDR/" + file.getName().replace(".in", ".out"); | |
File outfile = new File(outfileName); | |
outfile.getParentFile().mkdirs(); | |
outfile.createNewFile(); | |
PrintWriter printWriter = new PrintWriter(new FileWriter(outfileName)); | |
for (String cidr : res) { | |
printWriter.print(cidr + " "); | |
} | |
printWriter.close(); | |
} | |
} | |
public List<String> ipToCIDR(String ip, long n) { | |
List<String> result = new ArrayList<>(); | |
long ipNum = 0; | |
String[] tokens = ip.split("\\."); | |
for (int i = 0; i < 4; i++) { | |
ipNum = ipNum * 256 + (long) Integer.parseInt(tokens[i]); | |
} | |
if (n + ipNum > 4294967296L) { | |
return result; | |
} else if (n == 4294967296L) { | |
result.add("0.0.0.0/0"); | |
return result; | |
} | |
long cnt = 0; | |
while(cnt < n) { | |
// get rightmost set bit | |
long x = ipNum & -ipNum; | |
if (x == 0) { | |
x = 1; | |
while((x << 1) <= n) { | |
x <<= 1; | |
} | |
} else { | |
while(cnt + x > n) { | |
x >>= 1; | |
} | |
} | |
cnt += x; | |
result.add(toCIDR(ipNum, x)); | |
ipNum += x; | |
} | |
return result; | |
} | |
public String toCIDR(long num, long x) { | |
int cnt = 0; | |
while(x > 0) { | |
x >>= 1; | |
cnt += 1; | |
} | |
int[] ip = new int[4]; | |
for (int i = 3; i >= 0; i--) { | |
ip[i] = (int) num & 255; | |
num >>= 8; | |
} | |
StringBuilder sb = new StringBuilder(); | |
for (int i = 0; i < 4; i++) { | |
sb.append(ip[i]).append("."); | |
} | |
sb.setLength(sb.length() - 1); | |
int preBit = 32 - (cnt - 1); | |
sb.append("/").append(preBit); | |
return sb.toString(); | |
} | |
private int getInt(String name) { | |
return Integer.parseInt(name.replaceAll("\\D", "")); | |
} | |
private File[] readFolder(String path) { | |
File folder = new File(path); | |
File[] files = folder.listFiles(); | |
Arrays.sort(files, (a, b) -> getInt(a.getName()) - getInt(b.getName())); | |
return files; | |
} | |
private CIDR.InputValues readFile(File file) { | |
try { | |
// assume the input file is always valid | |
Scanner sc = new Scanner(file); | |
String ip = sc.nextLine().trim(); | |
long n = Long.parseLong(sc.nextLine().trim()); | |
return new CIDR.InputValues(ip, n); | |
} catch (FileNotFoundException e) { | |
System.out.println(file.getName() + " not exist"); | |
} | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment