Created
July 3, 2013 09:42
-
-
Save bingoohuang/5916691 to your computer and use it in GitHub Desktop.
find country code by ip using ip ranges implemented by TreeMap
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
/** | |
* 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