From 081dace1c8497645018e89c77ef4afb79df2f295 Mon Sep 17 00:00:00 2001 From: IP2Location Date: Tue, 14 Nov 2023 13:29:06 +0800 Subject: [PATCH] Fixed wrong value returned by CIDRToIPv6 function --- ip2location.go | 2 +- iptools.go | 54 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/ip2location.go b/ip2location.go index 4f4a6d5..62db7ec 100644 --- a/ip2location.go +++ b/ip2location.go @@ -159,7 +159,7 @@ var district_position = [27]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 var asn_position = [27]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24} var as_position = [27]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25} -const api_version string = "9.6.0" +const api_version string = "9.6.1" var max_ipv4_range = uint128.From64(4294967295) var max_ipv6_range = uint128.From64(0) diff --git a/iptools.go b/iptools.go index 5b9786f..9808698 100644 --- a/iptools.go +++ b/iptools.go @@ -448,31 +448,43 @@ func (t *IPTools) CIDRToIPv6(CIDR string) ([]string, error) { return nil, errors.New("Not a valid CIDR.") } - hexstartaddress, _ := t.ExpandIPv6(ip) - hexstartaddress = strings.ReplaceAll(hexstartaddress, ":", "") - hexendaddress := hexstartaddress - - bits := 128 - prefix - pos := 31 - - for bits > 0 { - values := []int{4, bits} - min, _ := t.minMax(values) - x, _ := strconv.ParseInt(string(hexendaddress[pos]), 16, 64) - y := fmt.Sprintf("%x", (x | int64(math.Pow(2, float64(min))-1))) + expand, _ := t.ExpandIPv6(ip) + parts := strings.Split(expand, ":") + + bitStart := strings.Repeat("1", prefix) + strings.Repeat("0", 128-prefix) + bitEnd := strings.Repeat("0", prefix) + strings.Repeat("1", 128-prefix) + + n := 16 // split string into 16-char parts + floors := []string{} + for i := 0; i < len(bitStart); i += n { + end := i + n + if end > len(bitStart) { + end = len(bitStart) + } + floors = append(floors, bitStart[i:end]) + } + ceilings := []string{} + for i := 0; i < len(bitEnd); i += n { + end := i + n + if end > len(bitEnd) { + end = len(bitEnd) + } + ceilings = append(ceilings, bitEnd[i:end]) + } - hexendaddress = hexendaddress[:pos] + y + hexendaddress[pos+1:] + start := []string{} + end := []string{} - bits = bits - 4 - pos = pos - 1 + for i := 0; i < 8; i += 1 { + p, _ := strconv.ParseUint(parts[i], 16, 64) + f, _ := strconv.ParseUint(floors[i], 2, 64) + c, _ := strconv.ParseUint(ceilings[i], 2, 64) + start = append(start, strconv.FormatUint(p&f, 16)) + end = append(end, strconv.FormatUint(p|c, 16)) } - re2 := regexp.MustCompile(`(.{4})`) - hexstartaddress = re2.ReplaceAllString(hexstartaddress, "$1:") - hexstartaddress = strings.TrimSuffix(hexstartaddress, ":") - hexendaddress = re2.ReplaceAllString(hexendaddress, "$1:") - hexendaddress = strings.TrimSuffix(hexendaddress, ":") - + hexstartaddress, _ := t.ExpandIPv6(strings.Join(start, ":")) + hexendaddress, _ := t.ExpandIPv6(strings.Join(end, ":")) result := []string{hexstartaddress, hexendaddress} return result, nil