3

HTTP解析ライブラリを作成しています(純粋なDで適切なライブラリが見つからなかったため)。IPアドレスを検証できる必要があるため(URIフィールド用)、IPアドレスを検証するための関数をいくつか作成しました。 :

IPv4の場合:

bool isIPv4(string addr) {
    int parts;
    ulong idx;

    foreach (i, c; addr) {
        if (c == '.') {
            if (i == 0) {
                return false;
            }

            if (to!int(addr[idx..i]) > 255) {
                return false;
            }

            parts++;
            if (parts > 3) {
                return false;
            }

            idx = i + 1;
        } else if (!isDigit(c)) {
            return false;
        }
    }

    if (to!int(addr[idx..addr.length]) > 255) {
        return false;
    }

    if (parts != 3) {
        return false;
    }

    return true;
}

そしてIPv6の場合:

bool isIPv6(string addr) {
    bool isColon, hasSeparator, hasIPv4;
    int leftChunks, rightChunks, digits;

    foreach (i, c; addr) {
        if (isHexDigit(c)) {
            digits = isColon ? 1 : digits + 1;
            isColon = false;

            if (digits == 1) {
                if (hasSeparator) {
                    rightChunks++;
                } else {
                    leftChunks++;
                }
            } else if (digits > 4) {
                return false;
            }
        } else if (c == ':') {
            if (isColon) {
                // multiple :: separators not allowed
                // as is :::
                if (hasSeparator) {
                    return false;
                }
                hasSeparator = true;
            } else {
                isColon = true;
            }
        } else if (c == '.') {
            if (hasSeparator) {
                rightChunks--;
            } else {
                leftChunks--;
            }

            if (!isIPv4(addr[i - digits .. addr.length])) {
                return false;
            }

            hasIPv4 = true;
            break;
        }
    }

    if (hasIPv4) {
        if (hasSeparator) {
            if (rightChunks + leftChunks > 5) {
                return false;
            }
        } else if (leftChunks != 6) {
            return false;
        }
    } else if (digits > 0) {
        if (hasSeparator) {
            if (rightChunks + leftChunks > 7) {
                return false;
            }
        } else if (leftChunks != 8) {
            return false;
        }
    }

    return true;
}

最初はIPv6の正規表現を作成しようとしましたが、特に特殊なケース()が非常に多いため、それは苦痛::でした。また、非常に長いため、正規表現のコンパイルのバグに遭遇したと思います。もちろん、これを行うためにいくつかの標準関数を使用したいと思います。

FWIW、私はstd.arrays.splitを使用してIPv4バリデーターを実装しましたが、それ以外の場合はstd.conv.to!intからの例外を検出またはキャッチする必要があるため、この方法で実装することにしました。

本当にありがとう!

ノート

最終的には、Phobosに書き込んだコードの一部を取得したいので、コードをできるだけ堅固にしたいと思います。

4

4 に答える 4

2

std.socketのparseAddressはどうですか?

于 2012-02-23T02:43:03.920 に答える
1

@tjameson:ずっと前に、私は自分のuriモジュールをハッキングしました。コードは次のとおりです:http://codepad.org/PBm5BEVP。私はいつもそのモジュールに戻って改善し、GitHubでプルリクエストを送信したいと思っていましたが、それを行う時間がありませんでした... URI RFCには、URI内のIPv6アドレスを解析するための正規表現もあります。これは間違いなく何かです。このコードを入れます。

于 2012-02-22T23:15:27.470 に答える
0

OSが提供するinet_pton()関数を使用できます。アドレスを解析し、それが間違っているかどうかを通知します。http://www.kernel.org/doc/man-pages/online/pages/man3/inet_pton.3.htmlを参照してください

IPv4アドレスとIPv6アドレスの両方を解析し、inet_ntop()を使用して、解析されたアドレスを正規の表記に戻すことができます。

于 2012-02-22T21:56:32.747 に答える
0

試す:

IPv4

/^(((2[0-4]|1\d|[1-9])?\d|25[0-5])(\.(?!$)|$)){4}$

IPv6

/^((?=(?=(.*?::))\2(?!.+::))(::)?([\dA-F]{1,4}:(:|(?!$))|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:(?!$)|$))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])(\.(?!$)|$)){4})$/i

(ECMAscript構文を使用)

差出人:http : //home.deds.nl/~aeron/regex/

于 2012-03-16T21:06:17.667 に答える