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に書き込んだコードの一部を取得したいので、コードをできるだけ堅固にしたいと思います。