identificar se os endereços IP na lista A existem em uma lista de intervalos de IP na lista B

identificar se os endereços IP na lista A existem em uma lista de intervalos de IP na lista B

Eu tenho 2 listas, uma contendo todos os endereços IP de 32 bits e a outra é uma lista de intervalos de IP e outros endereços IP. Preciso descobrir se cada IP da lista A existe em qualquer intervalo de IP ou endereço da lista B. O resultado final seria exibir os endereços da lista A que não existem na lista B. Isso seria fácil usando diff se o IP intervalos não estavam envolvidos. A lista em si contém quase 10.000 linhas, portanto, passar por isso manualmente levaria uma eternidade.

Responder1

Este script funciona no Linux/Bash. Não tenho certeza se está livre de bugs. Comente se quiser alguma explicação.

#!/bin/bash

# The script prints addresses from one file that are NOT
# in the ranges provided in another file.

# $1 is the file with addresses to check
# $2 is the file that holds the ranges
## in format x.x.x.x-y.y.y.y or as a single IP, one per line.

### Variables ###

inFile="$1"
rangesFile="$2"
typeset -a rangesLow rangesHigh #arrays of int
rangesCount=


### Functions ###

toInt () {
    printf "%d\n" $(($1*256*256*256 + $2*256*256 + $3*256 + $4))
}

readRanges () {
    while IFS=- read -a range
    do
        IFS=. read -a low <<< "${range[0]}"
        [ -z "${range[1]}" ] && range[1]="${range[0]}"
        IFS=. read -a high <<< "${range[1]}"
        rangesLow+=( $(toInt "${low[@]}") )
        rangesHigh+=( $(toInt "${high[@]}") )
    done < "$rangesFile"
    rangesCount=${#rangesLow[@]}
}

singleCheck () {
    # $1 is the address to check.
    # $2 and $3 are the bounds, low and high.
    # Returns 0 if NOT in range.

    [[ $1 -ge $2 ]] && [[ $1 -le $3 ]] && return 1
    # To invert the logic of the script, instead of the line above
    ## use this one:
    # [[ $1 -ge $2 ]] && [[ $1 -le $3 ]] || return 1
    return 0
}

addressCheck () {
    # The function takes in 4 octets of an IP as four positional parameters.
    # Returns 1 if IP is in any range.
    # If not in range, the address is printed to stdout.
    local address
    address=$(toInt "$@")
    for ((i=0; i<rangesCount ; i++)) # Loop for all ranges.
    do
        singleCheck "$address" "${rangesLow[$i]}" "${rangesHigh[$i]}" || return 1 
    done    
    printf "%d.%d.%d.%d\n" "$@"
}

checkAll () {
    while IFS=. read -a toCheck
    do
        addressCheck "${toCheck[@]}"
    done < "$inFile"
}

main () {
    readRanges
    checkAll
}

### Execute ###

main

Baseado no pensamento brilhante de Hymie.

Responder2

Não conheço um script de shell, mas um programa deve ser capaz de converter ambas as listas de endereços IP quádruplos pontilhados em números inteiros únicos e, em seguida, comparar os números com o padrão maior que menor que.

i = (first octet * 256*256*256) + (second octet * 256*256)
  + (third octet * 256) + (fourth octet)

informação relacionada