golang español address go ip-address

español - Go/GoLang comprueba la dirección IP en el rango



enter ip address en español (5)

¿Qué tal alguna implementación como inet_pton? El resultado es fácil de almacenar.

func IP2Integer(ip *net.IP) (int64, error) { ip4 := ip.To4() if ip4 == nil { return 0, fmt.Errorf("illegal: %v", ip) } bin := make([]string, len(ip4)) for i, v := range ip4 { bin[i] = fmt.Sprintf("%08b", v) } return strconv.ParseInt(strings.Join(bin, ""), 2, 64) }

En Go / GoLang, ¿cuál es la forma más rápida de verificar si una dirección IP está dentro de un rango específico?

Por ejemplo, dado el rango 216.14.49.184 a 216.14.49.191 , ¿cómo puedo verificar si una dirección IP de entrada dada está en ese rango?


Esto ya está en stdlib en el paquete "net" como una función llamada net.Contains. ¡No necesitas reescribir el código que ya existe!

Vea la documentación here .

Para usarlo solo hay que analizar las subredes deseadas.

network := "192.168.5.0/24" clientips := []string{ "192.168.5.1", "192.168.6.0", } _, subnet, _ := net.ParseCIDR(network) for _, clientip := range clientips { ip := net.ParseIP(clientip) if subnet.Contains(ip) { fmt.Println("IP in subnet", clientip) } }

En caso de que el código anterior no tenga sentido aquí es un enlace de Google Play


La versión genérica para ipv4 / ipv6.

ip.go:

package ip import ( "bytes" "net" "github.com/golang/glog" ) //test to determine if a given ip is between two others (inclusive) func IpBetween(from net.IP, to net.IP, test net.IP) bool { if from == nil || to == nil || test == nil { glog.Warning("An ip input is nil") // or return an error!? return false } from16 := from.To16() to16 := to.To16() test16 := test.To16() if from16 == nil || to16 == nil || test16 == nil { glog.Warning("An ip did not convert to a 16 byte") // or return an error!? return false } if bytes.Compare(test16, from16) >= 0 && bytes.Compare(test16, to16) <= 0 { return true } return false }

y ip_test.go:

package ip import ( "net" "testing" ) func TestIPBetween(t *testing.T) { HandleIpBetween(t, "0.0.0.0", "255.255.255.255", "128.128.128.128", true) HandleIpBetween(t, "0.0.0.0", "128.128.128.128", "255.255.255.255", false) HandleIpBetween(t, "74.50.153.0", "74.50.153.4", "74.50.153.0", true) HandleIpBetween(t, "74.50.153.0", "74.50.153.4", "74.50.153.4", true) HandleIpBetween(t, "74.50.153.0", "74.50.153.4", "74.50.153.5", false) HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "74.50.153.4", "74.50.153.2", false) HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", "2001:0db8:85a3:0000:0000:8a2e:0370:7334", true) HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", "2001:0db8:85a3:0000:0000:8a2e:0370:7350", true) HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", true) HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", "2001:0db8:85a3:0000:0000:8a2e:0370:8335", false) HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.127", false) HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.128", true) HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.129", true) HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.250", true) HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.251", false) HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "192.0.2.130", true) HandleIpBetween(t, "192.0.2.128", "192.0.2.250", "::ffff:192.0.2.130", true) HandleIpBetween(t, "idonotparse", "192.0.2.250", "::ffff:192.0.2.130", false) } func HandleIpBetween(t *testing.T, from string, to string, test string, assert bool) { res := IpBetween(net.ParseIP(from), net.ParseIP(to), net.ParseIP(test)) if res != assert { t.Errorf("Assertion (have: %s should be: %s) failed on range %s-%s with test %s", res, assert, from, to, test) } }


Las direcciones IP se representan como segmentos de []byte bigendianos []byte en go (el tipo de IP ), por lo que se compararán correctamente usando bytes.Compare .

Por ejemplo

package main import ( "bytes" "fmt" "net" ) var ( ip1 = net.ParseIP("216.14.49.184") ip2 = net.ParseIP("216.14.49.191") ) func check(ip string) bool { trial := net.ParseIP(ip) if trial.To4() == nil { fmt.Printf("%v is not an IPv4 address/n", trial) return false } if bytes.Compare(trial, ip1) >= 0 && bytes.Compare(trial, ip2) <= 0 { fmt.Printf("%v is between %v and %v/n", trial, ip1, ip2) return true } fmt.Printf("%v is NOT between %v and %v/n", trial, ip1, ip2) return false } func main() { check("1.2.3.4") check("216.14.49.185") check("1::16") }

Lo que produce

1.2.3.4 is NOT between 216.14.49.184 and 216.14.49.191 216.14.49.185 is between 216.14.49.184 and 216.14.49.191 1::16 is not an IPv4 address


Pagué el código de un ejemplo de C # encontrado aquí: https://.com/a/2138724/1655418

Y por alguna razón, termina siendo 1 ms más rápido que la solución de Nick.

Mi pregunta era por la forma "más rápida", así que pensé en publicar la mía y ver qué pensaba la comunidad.

package iptesting import ( "fmt" "testing" "net" "time" "bytes" ) func TestIPRangeTime(t *testing.T) { lowerBytes := net.ParseIP("216.14.49.184").To4() upperBytes := net.ParseIP("216.14.49.191").To4() inputBytes := net.ParseIP("216.14.49.184").To4() startTime := time.Now() for i := 0; i < 27000; i++ { IsInRange(inputBytes, lowerBytes, upperBytes) } endTime := time.Now() fmt.Println("ELAPSED time port: ", endTime.Sub(startTime)) lower := net.ParseIP("216.14.49.184") upper := net.ParseIP("216.14.49.191") trial := net.ParseIP("216.14.49.184") startTime = time.Now() for i := 0; i < 27000; i++ { IsInRange2(trial, lower, upper) } endTime = time.Now() fmt.Println("ELAPSED time bytescompare: ", endTime.Sub(startTime)) } func IsInRange2(trial net.IP, lower net.IP, upper net.IP) bool { if bytes.Compare(trial, lower) >= 0 && bytes.Compare(trial, upper) <= 0 { return true } return false } func IsInRange(ip []byte, lower []byte, upper []byte) bool { //fmt.Printf("given ip len: %d/n", len(ip)) lowerBoundary := true upperBoundary := true for i := 0; i < len(lower) && (lowerBoundary || upperBoundary); i++ { if lowerBoundary && ip[i] < lower[i] || upperBoundary && ip[i] > upper[i] { return false } if ip[i] == lower[i] { if lowerBoundary { lowerBoundary = true } else { lowerBoundary = false } //lowerBoundary &= true } else { lowerBoundary = false //lowerBoundary &= false } if ip[i] == upper[i] { //fmt.Printf("matched upper/n") if upperBoundary { upperBoundary = true } else { upperBoundary = false } //upperBoundary &= true } else { upperBoundary = false //upperBoundary &= false } } return true }

Mis resultados:

=== RUN TestIPRangeTime ELAPSED time port: 1.0001ms ELAPSED time bytescompare: 2.0001ms --- PASS: TestIPRangeTime (0.00 seconds) === RUN TestIPRangeTime ELAPSED time port: 1ms ELAPSED time bytescompare: 2.0002ms --- PASS: TestIPRangeTime (0.00 seconds) === RUN TestIPRangeTime ELAPSED time port: 1.0001ms ELAPSED time bytescompare: 2.0001ms --- PASS: TestIPRangeTime (0.00 seconds) === RUN TestIPRangeTime ELAPSED time port: 1.0001ms ELAPSED time bytescompare: 2.0001ms --- PASS: TestIPRangeTime (0.00 seconds)