Skip to content

Instantly share code, notes, and snippets.

@nirmalyaghosh
Created February 8, 2014 15:52
Show Gist options
  • Save nirmalyaghosh/8885782 to your computer and use it in GitHub Desktop.
Save nirmalyaghosh/8885782 to your computer and use it in GitHub Desktop.
A random but realistic IP address generator. It makes use of country specific CIDR address files read from the resource directory. Files can be downloaded from http://www.ip2location.com/free/visitor-blocker in the CIDR format (each line is similar to 222.165.0.0/17). For the purpose of testing, a few CIDR addresses have been selected for a few …
package net.nirmalya.util.ipaddr;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import org.apache.commons.net.util.SubnetUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Generates IP addresses based on randomly selected address block(s) read from country specific file(s) in the resource
* directory.
*
* @author Nirmalya Ghosh
*/
public class IPAddressGenerator {
private final boolean useSampleFile = true;
private static final IPAddressGenerator INSTANCE = new IPAddressGenerator();
private static Logger logger = LoggerFactory.getLogger(IPAddressGenerator.class);
private Map<Integer, String> lines = new HashMap<Integer, String>();
private Random random = new Random();
private String countryCodeLoaded;
public static String generateIPAddress(Country countryCode) {
return INSTANCE.generate(countryCode);
}
public static String[] generateIPAddresses(Country countryCode, int count) {
String[] ipAddresses = new String[count];
for (int i = 0; i < count; i++) {
ipAddresses[i] = INSTANCE.generate(countryCode);
}
return ipAddresses;
}
public static void main(String[] args) {
IPAddressGenerator.generateIPAddress(Country.SINGAPORE);
}
private IPAddressGenerator() {
}
private String generate(Country countryCode) {
loadCidrFile(countryCode);
int lineNumber = 1 + this.random.nextInt(this.lines.size());
String cidr = this.lines.get(lineNumber).trim();
while (cidr.endsWith("/31") || cidr.endsWith("/32")) {
// TODO figure out why exceptions are thrown when /31 and /32
cidr = this.lines.get(this.random.nextInt(this.lines.size()));
}
SubnetUtils util = new SubnetUtils(cidr);
String[] ipAddresses = util.getInfo().getAllAddresses();
int index = this.random.nextInt(ipAddresses.length);
String ipAddress = ipAddresses[index];
logger.debug("Selected {} (#{} of {} IP addresses based on {})", ipAddress, index, ipAddresses.length, cidr);
return ipAddress;
}
private void loadCidrFile(Country country) {
if ((this.countryCodeLoaded != null) && (this.countryCodeLoaded.equals(country.getCode()))) {
return;
}
this.lines.clear();
String cidrFileName = String.format((useSampleFile ? "sample-" : "") + "cidr-%s.txt", country.getCode());
InputStream inputStream = IPAddressGenerator.class.getResourceAsStream(cidrFileName);
int lineNumber = 0;
try (Scanner scanner = new Scanner(inputStream)) {
while (scanner.hasNextLine()) {
this.lines.put(++lineNumber, scanner.nextLine());
}
this.countryCodeLoaded = country.getCode();
logger.debug("{} lines read from {}", this.lines.size(), cidrFileName);
} catch (Exception e) {
logger.debug("Caught an exception whilst reading {} {}", cidrFileName, e);
}
}
}
/**
* Represents the country codes. Used to refer to specific configuration files.
*
* @author Nirmalya Ghosh
*/
public enum Country {
AUSTRALIA("AU"),
CHINA("CN"),
INDIA("IN"),
SINGAPORE("SG");
private String code;
private Country(String countryCode) {
this.code = countryCode;
}
public String getCode() {
return code;
}
}
37.139.65.0/24
59.167.87.0/24
101.160.198.0/24
163.232.0.0/15
210.193.128.0/17
112.64.0.0/14
180.208.0.0/15
202.152.176.0/20
203.12.130.0/24
210.31.0.0/17
14.139.0.0/16
27.56.0.0/13
59.145.0.0/17
59.164.0.0/15
61.246.57.0/24
112.110.0.0/16
113.19.0.0/16
114.143.186.0/24
116.119.0.0/16
121.242.0.0/16
122.160.0.0/12
125.20.0.0/24
171.48.0.0/12
202.144.0.0/17
202.157.64.0/24
203.88.128.0/19
220.156.184.0/21
223.224.0.0/12
218.186.0.0/16
219.74.0.0/16
220.255.0.0/16
221.128.0.0/18
222.165.0.0/17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment