быстрый способ поиска IP в большой список IP / подсети на Голанге? - PullRequest
0 голосов
/ 20 ноября 2018

, пожалуйста, помогите мне решить следующую задачу как можно быстрее

У меня есть большой список IP / подсетей, таких как ...

35.132.199.128/27
8.44.144.248/32
87.117.185.193
45.23.45.45

и т. Д., И мне нужно будет найти некоторыеip в этом списке максимально быстро запускается в go.

, когда я пытаюсь использовать кусочек строк и диапазон, это было очень медленно в большом списке.

Могу ли я использовать карту, например строку map [string], и ее внешний вид можно использовать, но только для проверки ip, а не для проверки подсети.

Кто-нибудь может мне помочь с решением этой задачи?Благодарю.

мой код

func (app *application) validateIP(ip string) bool {

for _, item := range app.IPList {

    itemIsIP := net.ParseIP(item)

    if itemIsIP != nil {
        if ip == itemIsIP.String() {
            return true
        }
        continue
    }

    _, itemNet, err := net.ParseCIDR(item)
    if err != nil {
        log.Printf("[ERROR] %+v", err)
    }

    checkedIP := net.ParseIP(ip)

    if itemNet.Contains(checkedIP) {
        return true
    }
}
return false

}

1 Ответ

0 голосов
/ 20 ноября 2018

Мы решили эту проблему в нашем проекте:

isIPV4inCIDRList("35.132.199.128", []string{"35.132.199.128/27"})

func isIPV4inCIDRList(ip []byte, list []string) bool {
    for i := 0; i < 32; i++ {
        sm := strconv.Itoa(i)
        m, _ := mask(sm, 4)
        inv := andIP(ip, []byte(m))
        if len(inv) == 0 {
            continue
        }

        for _, cidr := range list {
            if cidr == inv.String() + "/" + sm {
                return true
            }
        }
    }

    return false
}

func andIP(ip, mask []byte) net.IP {
    inv := net.IP{}
    for i, v := range ip {
        inv = append(inv, mask[i]&v)
    }
    return inv
}

// Bigger than we need, not too big to worry about overflow
const big = 0xFFFFFF

// Decimal to integer.
// Returns number, characters consumed, success.
func dtoi(s string) (n int, i int, ok bool) {
    n = 0
    for i = 0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
        n = n*10 + int(s[i]-'0')
        if n >= big {
            return big, i, false
        }
    }
    if i == 0 {
        return 0, 0, false
    }
    return n, i, true
}

func mask(m string, iplen int) (net.IPMask, error) {
    n, i, ok := dtoi(m)
    if !ok || i != len(m) || n < 0 || n > 8*iplen {
        return nil, &net.ParseError{Type: "CIDR address"}
    }
    return net.CIDRMask(n, 8*iplen), nil
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...