Skip to content

Instantly share code, notes, and snippets.

@iddoeldor
Last active January 6, 2018 14:38
Show Gist options
  • Save iddoeldor/3a88c1fc1c7ca09618e3023cd0471bba to your computer and use it in GitHub Desktop.
Save iddoeldor/3a88c1fc1c7ca09618e3023cd0471bba to your computer and use it in GitHub Desktop.
reverse ip2country
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.nio.file.Files;
import java.nio.file.Paths;
import static java.nio.file.StandardOpenOption.*;
/**
* Reverse ip2country generator
* Iterating trough range of IP addresses, appending each ip to a file named by its country.
*
* TODO #1
* Optimization tip; if range of ips related to one country, which it mostly does,
* for example 200.58.0.0 .. 200.71.125.255 are US
* I should append to file the ip with wildcard on the subnet and not the whole range.
* Currently it's overkill and not in scope.
*
* Using Java 8 and com.maxmind.geoip2.geoip2 v2.10.0
* @author Iddo Eldor
*/
public class ReverseIP2Country {
private static final String DATABASE_FILE_LOCATION = "~/GeoIP2-City.mmdb";
private static final String DATA_FOLDER = "~/data/"; // files will be created in this folder (add write premission)
private static DatabaseReader databaseReader; // database interface
private static IPAddress fromIp = new IPAddress("200.57.200.1"); // will iterate with this object
private static final IPAddress TO_IP = new IPAddress("212.57.218.255"); // constant
public static void main(String args[])
throws IOException /* if file not found or cannot open */
{
databaseReader = new DatabaseReader.Builder(new File(DATABASE_FILE_LOCATION)).build();
// iterate over the range of IPs
do {
fromIp = fromIp.next();
String ip = fromIp.toString();
String country = getCountryNameByIP(ip);
// append ip to file named as country at /data, create file if not exist
Files.write(Paths.get(DATA_FOLDER + country), (ip + System.lineSeparator()).getBytes(), CREATE, APPEND);
System.out.println(ip);
} while (!fromIp.equals(TO_IP));
}
private static /*synchronized*/ String getCountryNameByIP(String ip) {
String result = null; // if country not found it will insert to a file named "null"
try {
result = databaseReader.city(InetAddress.getByName(ip)).getCountry().getName();
} catch (Exception ignored) {}
return result;
}
private static class IPAddress {
private final int value;
IPAddress(int value) {
this.value = value;
}
IPAddress(String stringValue) {
String[] parts = stringValue.split("\\.");
if (parts.length != 4) {
throw new IllegalArgumentException();
}
value =
(Integer.parseInt(parts[0], 10) << (8 * 3)) & 0xFF000000 |
(Integer.parseInt(parts[1], 10) << (8 * 2)) & 0x00FF0000 |
(Integer.parseInt(parts[2], 10) << (8 * 1)) & 0x0000FF00 |
(Integer.parseInt(parts[3], 10) << (8 * 0)) & 0x000000FF;
}
int getOctet(int i) {
if (i < 0 || i >= 4) throw new IndexOutOfBoundsException();
return (value >> (i * 8)) & 0x000000FF;
}
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 3; i >= 0; --i) {
sb.append(getOctet(i));
if (i != 0) sb.append(".");
}
return sb.toString();
}
@Override
public boolean equals(Object obj) {
return obj instanceof IPAddress && value == ((IPAddress) obj).value;
}
@Override
public int hashCode() {
return value;
}
IPAddress next() {
return new IPAddress(value + 1);
}
}
}
@iddoeldor
Copy link
Author

iddoeldor commented Nov 16, 2017

Iterated over 200.57.200.1..200.71.255.197 for test purpose, took 25seconds on on 16gb RAM 8 core pc
Results map :

  • Number of lines | Country (file name, null means not found)
    320824 Argentina
    288766 Mexico
    98304 Peru
    37896 Colombia
    28672 Chile
    27584 Venezuela
    25600 Ecuador
    23840 United States
    18432 Bolivia
    16704 Uruguay
    16384 Nicaragua
    6208 Brazil
    6144 Panama
    4096 Paraguay
    3160 Honduras
    2048 null
    2048 Dominican Republic
    2048 Costa Rica
    1991 Bonaire, Sint Eustatius, and Saba
    768 British Virgin Islands
    256 Curaçao
    8 Italy

    931781 total

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment