Parse an IP Address: Difference between revisions

Rename Perl 6 -> Raku, alphabetize, minor clean-up
(Added C++ solution)
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 1,005:
fmt parseaddr '[2605:2700:0:3::4713:93e3]:80'
ipv6 260527000000000300000000471393e3 80</lang>
 
 
=={{header|Java}}==
Line 1,493 ⟶ 1,492:
a::b::1
parse error</lang>
 
=={{header|Perl 6}}==
<lang perl6>grammar IP_Addr {
token TOP { ^ [ <IPv4> | <IPv6> ] $ }
 
token IPv4 {
[ <d8> +% '.' ] <?{ $<d8> == 4 }> <port>?
{ @*by8 = @$<d8> }
}
 
token IPv6 {
| <ipv6>
| '[' <ipv6> ']' <port>
}
 
token ipv6 {
| <h16> +% ':' <?{ $<h16> == 8 }>
{ @*by16 = @$<h16> }
 
| [ (<h16>) +% ':']? '::' [ (<h16>) +% ':' ]? <?{ @$0 + @$1 ≤ 8 }>
{ @*by16 = |@$0, |('0' xx 8 - (@$0 + @$1)), |@$1 }
 
| '::ffff:' <IPv4>
{ @*by16 = |('0' xx 5), 'ffff', |(by8to16 @*by8) }
}
 
token d8 { (\d+) <?{ $0 < 256 }> }
token d16 { (\d+) <?{ $0 < 65536 }> }
token h16 { (<:hexdigit>+) <?{ @$0 ≤ 4 }> }
 
token port {
':' <d16> { $*port = +$<d16> }
}
}
 
sub by8to16 (@m) { gather for @m -> $a,$b { take ($a * 256 + $b).fmt("%04x") } }
 
my @cases = <
127.0.0.1
127.0.0.1:80
::1
[::1]:80
2605:2700:0:3::4713:93e3
[2605:2700:0:3::4713:93e3]:80
2001:db8:85a3:0:0:8a2e:370:7334
2001:db8:85a3::8a2e:370:7334
[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443
192.168.0.1
::ffff:192.168.0.1
::ffff:71.19.147.227
[::ffff:71.19.147.227]:80
::
256.0.0.0
g::1
0000
0000:0000
0000:0000:0000:0000:0000:0000:0000:0000
0000:0000:0000::0000:0000
0000::0000::0000:0000
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
ffff:ffff:ffff:fffg:ffff:ffff:ffff:ffff
fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
fff:ffff:0:ffff:ffff:ffff:ffff:ffff
>;
 
for @cases -> $addr {
my @*by8;
my @*by16;
my $*port;
 
IP_Addr.parse($addr);
 
say $addr;
if @*by16 {
say " IPv6: ", @*by16.map({:16(~$_)})».fmt("%04x").join;
say " Port: ", $*port if $*port;
}
elsif @*by8 {
say " IPv4: ", @*by8».fmt("%02x").join;
say " Port: ", $*port if $*port;
}
else {
say " BOGUS!";
}
say '';
}</lang>
{{out}}
<pre>127.0.0.1
IPv4: 7f000001
 
127.0.0.1:80
IPv4: 7f000001
Port: 80
 
::1
IPv6: 00000000000000000000000000000001
 
[::1]:80
IPv6: 00000000000000000000000000000001
Port: 80
 
2605:2700:0:3::4713:93e3
IPv6: 260527000000000300000000471393e3
 
[2605:2700:0:3::4713:93e3]:80
IPv6: 260527000000000300000000471393e3
Port: 80
 
2001:db8:85a3:0:0:8a2e:370:7334
IPv6: 20010db885a3000000008a2e03707334
 
2001:db8:85a3::8a2e:370:7334
IPv6: 20010db885a3000000008a2e03707334
 
[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443
IPv6: 20010db885a308d313198a2e03707348
Port: 443
 
192.168.0.1
IPv4: c0a80001
 
::ffff:192.168.0.1
IPv6: 00000000000000000000ffffc0a80001
 
::ffff:71.19.147.227
IPv6: 00000000000000000000ffff471393e3
 
[::ffff:71.19.147.227]:80
IPv6: 00000000000000000000ffff471393e3
Port: 80
 
::
IPv6: 00000000000000000000000000000000
 
256.0.0.0
BOGUS!
 
g::1
BOGUS!
 
0000
BOGUS!
 
0000:0000
BOGUS!
 
0000:0000:0000:0000:0000:0000:0000:0000
IPv6: 00000000000000000000000000000000
 
0000:0000:0000::0000:0000
IPv6: 00000000000000000000000000000000
 
0000::0000::0000:0000
IPv6: 00000000000000000000000000000000
 
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
IPv6: ffffffffffffffffffffffffffffffff
 
ffff:ffff:ffff:fffg:ffff:ffff:ffff:ffff
BOGUS!
 
fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
IPv6: 0fffffffffffffffffffffffffffffff
 
fff:ffff:0:ffff:ffff:ffff:ffff:ffff
IPv6: 0fffffff0000ffffffffffffffffffff</pre>
 
=={{header|Phix}}==
Line 2,560 ⟶ 2,393:
[2605:2700:0:3::4713:93e3]:80 260527000000000300000000471393e3 ipv6 80
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
<lang perl6>grammar IP_Addr {
token TOP { ^ [ <IPv4> | <IPv6> ] $ }
 
token IPv4 {
[ <d8> +% '.' ] <?{ $<d8> == 4 }> <port>?
{ @*by8 = @$<d8> }
}
 
token IPv6 {
| <ipv6>
| '[' <ipv6> ']' <port>
}
 
token ipv6 {
| <h16> +% ':' <?{ $<h16> == 8 }>
{ @*by16 = @$<h16> }
 
| [ (<h16>) +% ':']? '::' [ (<h16>) +% ':' ]? <?{ @$0 + @$1 ≤ 8 }>
{ @*by16 = |@$0, |('0' xx 8 - (@$0 + @$1)), |@$1 }
 
| '::ffff:' <IPv4>
{ @*by16 = |('0' xx 5), 'ffff', |(by8to16 @*by8) }
}
 
token d8 { (\d+) <?{ $0 < 256 }> }
token d16 { (\d+) <?{ $0 < 65536 }> }
token h16 { (<:hexdigit>+) <?{ @$0 ≤ 4 }> }
 
token port {
':' <d16> { $*port = +$<d16> }
}
}
 
sub by8to16 (@m) { gather for @m -> $a,$b { take ($a * 256 + $b).fmt("%04x") } }
 
my @cases = <
127.0.0.1
127.0.0.1:80
::1
[::1]:80
2605:2700:0:3::4713:93e3
[2605:2700:0:3::4713:93e3]:80
2001:db8:85a3:0:0:8a2e:370:7334
2001:db8:85a3::8a2e:370:7334
[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443
192.168.0.1
::ffff:192.168.0.1
::ffff:71.19.147.227
[::ffff:71.19.147.227]:80
::
256.0.0.0
g::1
0000
0000:0000
0000:0000:0000:0000:0000:0000:0000:0000
0000:0000:0000::0000:0000
0000::0000::0000:0000
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
ffff:ffff:ffff:fffg:ffff:ffff:ffff:ffff
fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
fff:ffff:0:ffff:ffff:ffff:ffff:ffff
>;
 
for @cases -> $addr {
my @*by8;
my @*by16;
my $*port;
 
IP_Addr.parse($addr);
 
say $addr;
if @*by16 {
say " IPv6: ", @*by16.map({:16(~$_)})».fmt("%04x").join;
say " Port: ", $*port if $*port;
}
elsif @*by8 {
say " IPv4: ", @*by8».fmt("%02x").join;
say " Port: ", $*port if $*port;
}
else {
say " BOGUS!";
}
say '';
}</lang>
{{out}}
<pre>127.0.0.1
IPv4: 7f000001
 
127.0.0.1:80
IPv4: 7f000001
Port: 80
 
::1
IPv6: 00000000000000000000000000000001
 
[::1]:80
IPv6: 00000000000000000000000000000001
Port: 80
 
2605:2700:0:3::4713:93e3
IPv6: 260527000000000300000000471393e3
 
[2605:2700:0:3::4713:93e3]:80
IPv6: 260527000000000300000000471393e3
Port: 80
 
2001:db8:85a3:0:0:8a2e:370:7334
IPv6: 20010db885a3000000008a2e03707334
 
2001:db8:85a3::8a2e:370:7334
IPv6: 20010db885a3000000008a2e03707334
 
[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443
IPv6: 20010db885a308d313198a2e03707348
Port: 443
 
192.168.0.1
IPv4: c0a80001
 
::ffff:192.168.0.1
IPv6: 00000000000000000000ffffc0a80001
 
::ffff:71.19.147.227
IPv6: 00000000000000000000ffff471393e3
 
[::ffff:71.19.147.227]:80
IPv6: 00000000000000000000ffff471393e3
Port: 80
 
::
IPv6: 00000000000000000000000000000000
 
256.0.0.0
BOGUS!
 
g::1
BOGUS!
 
0000
BOGUS!
 
0000:0000
BOGUS!
 
0000:0000:0000:0000:0000:0000:0000:0000
IPv6: 00000000000000000000000000000000
 
0000:0000:0000::0000:0000
IPv6: 00000000000000000000000000000000
 
0000::0000::0000:0000
IPv6: 00000000000000000000000000000000
 
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
IPv6: ffffffffffffffffffffffffffffffff
 
ffff:ffff:ffff:fffg:ffff:ffff:ffff:ffff
BOGUS!
 
fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
IPv6: 0fffffffffffffffffffffffffffffff
 
fff:ffff:0:ffff:ffff:ffff:ffff:ffff
IPv6: 0fffffff0000ffffffffffffffffffff</pre>
 
=={{header|REXX}}==
10,333

edits