Last active
January 6, 2018 14:38
-
-
Save iddoeldor/3a88c1fc1c7ca09618e3023cd0471bba to your computer and use it in GitHub Desktop.
reverse ip2country
This file contains hidden or 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 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); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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