概要
文字列がIPv4形式かチェック、Inet4Address に変換するライブラリを作成しました。
また、大文字数字、記号のIPv4形式文字列(例 192.168.1.1)を許容します。
もとは、Inet4Address.getByName()を利用するお手軽な方法で判定していたのですがgetByNameのとある仕様(最後に記載)で不都合があったためライブラリを作成しました。
ライブラリ
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.regex.Pattern;
/** IPv4のユーティリティクラス */
public abstract class Ipv4AddressUtil {
/** 最大オクテット数 */
private static final int OCTETS_LENTGH = 4;
/** オクテット値の最大数 */
private static final int MAX_OCTET_VALUE = 255;
/** オクテット値の最小値 */
private static final int MIN_OCTET_VALUE = 0;
/** IPv4パターン */
private static final Pattern V4_FORMAT = Pattern
.compile("((([01]?\\d{1,2})|(2[0-4]\\d)|(25[0-5]))\\.){3}(([01]?\\d{1,2})|(2[0-4]\\d)|(25[0-5]))");
/**
* 指定された文字列がIPアドレスv4フォーマットか判定します。
* 以下の場合にIPアドレスv4フォーマットとみなします。
* ・ドットを区切り文字として、数字4組で構成される。
* ・数字は0~255の範囲の3桁以下の値である (ゼロパディング許容)。
*
* @param v 判定する文字列
* @return IPアドレスv4フォーマットの場合は true
*/
public static boolean isIpv4Address(String v) {
return isIpv4Address(v, true);
}
/**
* 指定された文字列がIPアドレスv4フォーマットか判定します。
* 以下の場合にIPアドレスv4フォーマットとみなします。
* ・ドットを区切り文字として、数字4組で構成される。
* ・数字は0~255の範囲の3桁以下の値である (ゼロパディング許容)。
*
* @param v 判定する文字列
* @param allowEm 全角を許容する。
* @return IPアドレスv4フォーマットの場合は true
*/
public static boolean isIpv4Address(String v, boolean allowEm) {
if (v == null || v.isEmpty()) {
return false;
}
if (allowEm) {
String[] octets = v.toLowerCase().replaceAll(".", ".").split("\\.");
if (octets.length != OCTETS_LENTGH) {
return false;
}
for (String octet : octets) {
try {
int b = Integer.parseInt(octet);
if (b < MIN_OCTET_VALUE || MAX_OCTET_VALUE < b)
return false;
} catch (NumberFormatException e) {
return false;
}
}
return true;
} else {
return V4_FORMAT.matcher(v).matches();
}
}
/**
* 指定された文字列をInet4Addressとして構文解析します。
* @param v 解析する文字列
* @param allowEm 全角を許容する。
* @return 文字列の引数で表されるInet4Address
* @throws IllegalArgumentException 文字列がIPアドレスv4フォーマットでない場合
*/
public static Inet4Address parseInet4Address(String v, boolean allowEm) throws IllegalArgumentException {
if (!isIpv4Address(v, allowEm))
throw new IllegalArgumentException("解析する文字列がIPアドレスv4フォーマットではありません。");
Inet4Address returnvalue = null;
try {
returnvalue = (Inet4Address) Inet4Address.getByName(v.toLowerCase().replaceAll(".", "."));
} catch (UnknownHostException e) {} // IPアドレスv4フォーマット確認済みのため、UnknownHostExceptionは発生しない。
return returnvalue;
}
}
あげぱんさんのコードがベースになります。ありがとうございます。
[Java][サンプルコード] IPアドレスフォーマットかチェックする - Javaのサンプルコード置いときますね http://javasampleokiba.blog.fc2.com/blog-entry-26.html
サンプルコード
Inet4Address.getByName()の挙動
InetAddress (Java Platform SE 6) https://docs.oracle.com/javase/jp/6/api/java/net/InetAddress.html#getByName(java.lang.String)
ホスト名は、「java.sun.com」などのマシン名か、またはその IP アドレスのテキスト表現です。リテラル IP アドレスが指定された場合、アドレス形式の有効性のみがチェックされます。
nullや空文字を与えると、ループバックインタフェースのアドレス(localhost/127.0.0.1)を返す仕様。(素直にUnknownHostExceptionを発生さえてくれたらいいのに。。)
また、IPv4文字列はすべて半角である必要もあります。
サンプルコード:https://paiza.io/projects/TA90Yho1C0BhGwIqwecACQ
参考
IPアドレスのフォーマットチェック | ハックノート http://hacknote.jp/archives/26988/
入力された文字がIPアドレスかのチェック -コンソール画面から入力をす- Java | 教えて!goo https://oshiete.goo.ne.jp/qa/5572521.html