RosettaCodeData/Task/Parse-an-IP-Address/Go/parse-an-ip-address.go
2015-02-20 09:02:09 -05:00

69 lines
1.3 KiB
Go

package main
import (
"errors"
"fmt"
"net"
"strconv"
"strings"
)
func ParseIPPort(s string) (ip net.IP, port, space string, err error) {
ip = net.ParseIP(s)
if ip == nil {
var host string
host, port, err = net.SplitHostPort(s)
if err != nil {
return
}
if port != "" {
// This check only makes sense if service names are not allowed
if _, err = strconv.ParseUint(port, 10, 16); err != nil {
return
}
}
ip = net.ParseIP(host)
}
if ip == nil {
err = errors.New("invalid address format")
} else {
space = "IPv6"
if ip4 := ip.To4(); ip4 != nil {
space = "IPv4"
ip = ip4
}
}
return
}
func main() {
var testCases = []string{
"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",
}
max := len("Input")
for _, addr := range testCases {
if len(addr) > max {
max = len(addr)
}
}
fmt.Printf("%-*s %*s %-6s %s\n", max, "Input",
2*net.IPv6len, "Address", "Space", "Port")
for _, addr := range testCases {
fmt.Printf("%-*s ", max, addr)
ip, port, space, err := ParseIPPort(addr)
if err != nil {
fmt.Println(err)
continue
}
fmt.Print(strings.Repeat(" ", net.IPv6len-len(ip)))
for _, b := range ip {
fmt.Printf("%02x", b)
}
fmt.Printf(" %-6s %s\n", space, port)
}
}