LoginSignup
4
3

More than 5 years have passed since last update.

IPv4形式の文字列かチェックするライブラリ

Posted at

概要

文字列が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

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3