Skip to content

Instantly share code, notes, and snippets.

@bingoohuang
Created July 3, 2013 09:42
Show Gist options
  • Save bingoohuang/5916691 to your computer and use it in GitHub Desktop.
Save bingoohuang/5916691 to your computer and use it in GitHub Desktop.
find country code by ip using ip ranges implemented by TreeMap
/**
* This utility provides methods to either convert an IPv4 address to its long format or a 32bit dotted format.
*
* @author Aion
* Created on 22/11/12
*/
public static class IPv4 {
/**
* Returns the long format of the provided IP address.
*
* @param ipAddress the IP address
* @return the long format of <code>ipAddress</code>
* @throws IllegalArgumentException if <code>ipAddress</code> is invalid
*/
public static long toLong(String ipAddress) {
if (ipAddress == null || ipAddress.isEmpty()) {
throw new IllegalArgumentException("ip address cannot be null or empty");
}
String[] octets = ipAddress.split(java.util.regex.Pattern.quote("."));
if (octets.length != 4) {
throw new IllegalArgumentException("invalid ip address");
}
long ip = 0;
for (int i = 3; i >= 0; i--) {
long octet = Long.parseLong(octets[3 - i]);
if (octet > 255 || octet < 0) {
throw new IllegalArgumentException("invalid ip address");
}
ip |= octet << (i * 8);
}
return ip;
}
/**
* Returns the 32bit dotted format of the provided long ip.
*
* @param ip the long ip
* @return the 32bit dotted format of <code>ip</code>
* @throws IllegalArgumentException if <code>ip</code> is invalid
*/
public static String toString(long ip) {
// if ip is bigger than 255.255.255.255 or smaller than 0.0.0.0
if (ip > 4294967295l || ip < 0) {
throw new IllegalArgumentException("invalid ip");
}
StringBuilder ipAddress = new StringBuilder();
for (int i = 3; i >= 0; i--) {
int shift = i * 8;
ipAddress.append((ip & (0xff << shift)) >> shift);
if (i > 0) {
ipAddress.append(".");
}
}
return ipAddress.toString();
}
}
public class IP2CountyCodeMap {
private final TreeMap<Long, CountryCodeEntry> ipMap = new TreeMap<Long, CountryCodeEntry>();
public void addIpRange(String startIp, String endIp, String countryCode) {
addIpRange(IPv4.toLong(startIp), IPv4.toLong(endIp), countryCode);
}
public void addIpRange(long startIp, long endIp, String countryCode) {
ipMap.put(startIp, new CountryCodeEntry(endIp, countryCode));
}
public String getCountryCode(String ip) {
return getCountryCode(IPv4.toLong(ip));
}
public String getCountryCode(long ip) {
Map.Entry<Long, CountryCodeEntry> entry = ipMap.floorEntry(ip);
if (entry != null && ip <= entry.getValue().endIpAddress) {
return entry.getValue().countryCode;
}
return null;
}
}
public class CountryCodeEntry {
public final long endIpAddress;
public final String countryCode;
public CountryCodeEntry (long endIpAddress, String countryCode) {
this.endIpAddress = endIpAddress;
this.countryCode = countryCode;
}
}
@Test
public void findCountryCodeByIP() throws Exception {
IP2CountyCodeMap IP2CountyCodeMap = new IP2CountyCodeMap();
IP2CountyCodeMap.addIpRange("192.168.0.0", "192.168.100.0", "aaa");
IP2CountyCodeMap.addIpRange("192.168.100.1", "192.168.200.0", "bbb");
IP2CountyCodeMap.addIpRange("192.168.200.1", "192.168.240.0", "ccc");
Assert.assertEquals("aaa", IP2CountyCodeMap.getCountryCode("192.168.9.9"));
Assert.assertEquals("bbb", IP2CountyCodeMap.getCountryCode("192.168.100.9"));
Assert.assertEquals("ccc", IP2CountyCodeMap.getCountryCode("192.168.200.9"));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment