まず第一に、住所がどのように書かれているか気にする必要はありません。inet_pton() はすべてのバリエーションを解析し、一貫した結果を提供します。これをバイナリ、16 進数、または必要なものに変換できます。
::192.168.0.1
のようなものを変換するためのすべてのコードは、0000:0000:0000:0000:0000:0000:c0a8:0001
実際には私の投稿にありました。それがまさに私のサンプル関数が行うことです。
inet_pton()にフィード0000:0000:0000:0000:0000:0000:192.168.0.1
し、次に inet_ntop() にフィードすると、正規の IPv6 表記が得られます::192.168.0.1
。この場合です。その文字列が で始まり::
、残りに:
3 つのドットが含まれている場合、それが IPv4 アドレスであると確信できます ;-)
前の質問への回答とこの質問を組み合わせるには:
function expand_ip_address($addr_str) {
/* First convert to binary, which also does syntax checking */
$addr_bin = @inet_pton($addr_str);
if ($addr_bin === FALSE) {
return FALSE;
}
$addr_hex = bin2hex($addr_bin);
/* See if this is an IPv4-Compatible IPv6 address (deprecated) or an
IPv4-Mapped IPv6 Address (used when IPv4 connections are mapped to
an IPv6 sockets and convert it to a normal IPv4 address */
if (strlen($addr_bin) == 16
&& substr($addr_hex, 0, 20) == str_repeat('0', 20)) {
/* First 80 bits are zero: now see if bits 81-96 are either all 0 or all 1 */
if (substr($addr_hex, 20, 4) == '0000')
|| substr($addr_hex, 20, 4) == 'ffff')) {
/* Remove leading bits so only the IPv4 bits remain */
$addr_bin = substr($addr_hex, 12);
}
}
/* Then differentiate between IPv4 and IPv6 */
if (strlen($addr_bin) == 4) {
/* IPv4: print each byte as 3 digits and add dots between them */
$ipv4_bytes = str_split($addr_bin);
$ipv4_ints = array_map('ord', $ipv4_bytes);
return vsprintf('%03d.%03d.%03d.%03d', $ipv4_ints);
} else {
/* IPv6: print as hex and add colons between each group of 4 hex digits */
return implode(':', str_split($addr_hex, 4));
}
}