アクセスログなどを解析する際、
「"127.0.0.1〜127.255.255.255"までのIPを検索したい」
というような事があるかと思います。
ただ、"127.0.0.1"のような形式のIPは、そのままだと文字列として扱われるので、IPを数値に変換しないと、範囲検索出来ません。
しかし、"127.0.0.1"のような形式のIPを数値に直すといっても、2進数や10進数に変換するのは面倒だし、直感的に扱いにくいと思います。
そこでちょっとした小細工により、簡単に数値化し、しかも直感的に扱いやすくする方法をメモします。
#方法概要
"127.0.0.1"のような値の、"."で分かれている数値の1つ1つは、0〜255までの数値になります。
そこで、それぞれの数値に、3桁分の容量を確保した上で数値にします。
例えば、
127.0.0.1
↓
127000000001
210.171.13.0
↓
210171013000
のように、変換していきます。
「0」「13」 のような3桁に満たない数値部分を、「000」「013」のように3桁に増やしているのがポイントです。
具体的には、IPを"."で分割して4つに分け、左からそれぞれ、
1000の3条の倍数、1000の2乗の倍数、1000の倍数、1の倍数
とみなして計算し、値を足します。
例えば
192.168.20.1
なら
(192 * 1000 * 1000 * 1000) + (168 * 1000 * 1000) + (20 * 1000) + 1
= 192000000000 + 168000000 + 20000 + 1
= 192168020001
のようになります。
4つに分割したIPのうち、一番左以外を3桁まで0埋めする、という方法でも結果は一緒です。
手動で変換する場合は、こちらの方がやりやすいでしょう。
192.168.20.1
↓
192.168.020.001
↓
192168020001
のように変換します。
このようなやり方でIPを数値に変換し、DBなどに保存しておくとよいでしょう。
#変換プログラム例
public static void main(String args[]){
{
String ip = "111.111.111.111";
long ipNum = ipToNum(ip);
System.out.println("IP before : " + ip + " IP after : " + ipNum);
}
{
String ip = "192.168.20.1";
long ipNum = ipToNum(ip);
System.out.println("IP before : " + ip + " IP after : " + ipNum);
}
{
String ip = "1.2.3.4";
long ipNum = ipToNum(ip);
System.out.println("IP before : " + ip + " IP after : " + ipNum);
}
}
/**
* IPを数値に変換する
* @param ip
* @return
*/
private static long ipToNum(String ip) {
// . で分割して4つにする
String[] ipParts = ip.split("\\.");
// 分割した数値を、それぞれ 1000の3条の倍数、1000の2乗の倍数、1000の倍数、1の倍数とみなして変換してから足し合わせる
long ipNum = multiplicationFromStr(ipParts[0], 1000 * 1000 * 1000) + multiplicationFromStr(ipParts[1], 1000 * 1000) + multiplicationFromStr(ipParts[2], 1000) + multiplicationFromStr(ipParts[3], 1);
return ipNum;
}
/**
* 指定された文字列xを数値に変換してyと掛け算を行う
* @param xStr
* @param y
* @return
*/
private static long multiplicationFromStr(String xStr, long y){
Long x = Long.parseLong(xStr);
return x * y;
}
出力結果
IP before : 111.111.111.111 IP after : 111111111111
IP before : 192.168.20.1 IP after : 192168020001
IP before : 1.2.3.4 IP after : 1002003004