목록 A의 IP 주소가 목록 B의 IP 범위 목록 내에 존재하는지 식별

목록 A의 IP 주소가 목록 B의 IP 범위 목록 내에 존재하는지 식별

2개의 목록이 있습니다. 하나는 32비트 IP 주소를 모두 포함하고, 다른 하나는 IP 범위 및 기타 IP 주소 목록입니다. 목록 A 내의 각 IP가 목록 B의 IP 범위 또는 주소에 존재하는지 확인해야 합니다. 최종 결과는 목록 B에 존재하지 않는 목록 A의 주소를 표시하는 것입니다. IP가 IP인 경우 diff를 사용하면 쉬울 것입니다. 범위는 포함되지 않았습니다. 목록 자체에는 거의 10,000줄이 포함되어 있으므로 이를 수동으로 처리하려면 시간이 오래 걸립니다.

답변1

이 스크립트는 Linux/Bash에서 트릭을 수행합니다. 버그가 없는지 잘 모르겠습니다. 설명을 원하시면 댓글을 달아주세요.

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

hymie의 빛나는 생각을 바탕으로.

답변2

쉘 스크립트에 대해서는 모르지만 프로그램은 점으로 구분된 쿼드 IP 주소의 두 목록을 단일 정수로 변환한 다음 숫자를 표준 큼-보다 작음과 비교할 수 있어야 합니다.

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

관련 정보