identificar si las direcciones IP en la lista A existen dentro de una lista de rangos de IP en la lista B

identificar si las direcciones IP en la lista A existen dentro de una lista de rangos de IP en la lista B

Tengo 2 listas, una que contiene todas las direcciones IP de 32 bits y la otra es una lista de rangos de IP y otras direcciones IP. Necesito encontrar si cada IP dentro de la lista A existe en algún rango de IP o dirección en la lista B. El resultado final sería mostrar las direcciones de la lista A que no existen en la lista B. Esto sería fácil usando diff si la IP Los rangos no estuvieron involucrados. La lista en sí contiene casi 10.000 líneas, por lo que revisarla manualmente llevaría una eternidad.

Respuesta1

Este script funciona en Linux/Bash. No estoy seguro de si está libre de errores. Comenta si quieres alguna explicación.

#!/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

Basado en el brillante pensamiento de hymie.

Respuesta2

No conozco un script de shell, pero un programa debería poder convertir ambas listas de direcciones IP de cuatro puntos en números enteros simples y luego comparar los números con el estándar mayor que menor que.

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

información relacionada