IPv4 계산을 위한 비트 연산

비트 연산에 대해 읽거나 들었을 때 종종 말합니다. 네, 알아두면 좋겠지만 소프트웨어 엔지니어로서의 일상 업무에서 자주 다룰 필요는 없습니다. 특히 더 높은 수준의 앱에서 작업할 때 그렇습니다. 그것이 사실일 수도 있지만 제 생각에는 매우 유용한 비트 연산에 대한 한 가지 사용 사례가 있으며 IP 주소가 주어진 서브넷에 있는지 여부를 확인하는 것이 중요합니다. 이를 작동시키려면 기본적으로 서브넷 마스크의 비트와 시작 주소를 사용하여 비트별& 연산으로 IP 주소의 비트를 검증합니다. 혼란스러운? 글쎄요 😅 그런 것들을 단계별로 그리는 것이 항상 더 낫습니다. 지금 시도하고 조금 더 설명하겠습니다.

서브넷 마스크가 255.255.255.192이고 시작 주소가 192.168.50.65인 매우 작은 네트워크가 있다고 가정해 보겠습니다. 다음으로 두 개의 IP 주소192.168.50.20192.168.50.80를 사용하겠습니다.
예, 어떤 주소가 네트워크에 있고 어떤 주소가 아닌지 눈으로 보는 것이 꽤 분명하다는 것을 알고 있습니다. 그러나 예와 단순함을 위해 그렇게 할 것입니다.

따라서 먼저 예제 주소를 살펴보고 비트로 표현하면 어떻게 생겼는지 살펴보겠습니다.



이제 보시다시피 서브넷 마스크는 네트워크 ID 섹션에 항상 1 비트가 있고 호스트 ID 섹션에 0 비트가 있습니다. 이 비트 배열은 가능한 모든 서브넷 마스크에 적용되며 정확히 이 동작을 사용하여 목표를 달성할 수 있습니다.

네트워크 ID와 호스트 ID가 무엇인지 혼란스럽다면 다음과 같이 말씀드리겠습니다.

네트워크 ID



A network ID or NetID is the fragment of IP address
that classifies the network for a specified host i.e.,
it tells us which network the host belongs to.


호스트 ID



It is the fragment of an IP address that uniquely
classifies a host on a specified TCP/IP network.



이 인용문의 출처 및 자세한 내용은 찾을 수 있습니다here.

작업으로 돌아가서 이제 서브넷 마스크의 비트와 시작 주소를 사용하여 비트 단위& 연산으로 일종의 유효성 검사 비트를 생성해 보겠습니다.



비트&가 어떻게 작동하는지 잊어버린 경우 here을 찾아볼 수 있습니다. 또는 1 & 1 = 1 및 기타 모든 가능성= 0을 염두에 두십시오 😉

이제 우리는 두 개의 IP 주소에 대해 동일한 작업을 수행하고 결과를 유효성 검사 비트와 비교하여 일치하는 경우 IP가 주어진 네트워크에 있음을 알 수 있습니다.

첫 번째 IP192.168.50.20부터 시작:


유효성 검사 비트가 내가 빨간색으로 표시한 결과와 일치하지 않는 것을 볼 수 있습니다. 따라서 이 IP는 우리 네트워크에 없습니다. 이제 두 번째 주소에 대해 동일한 작업을 수행하면 다음과 같습니다.


경기입니다 🎉

이제 실제로 구현하기 위한 코드 예제를 진행하기 전에. 직접 해 보고 싶다면 내가 만든 codewars katahere에서 구현을 연습할 수 있습니다. 아직 베타 버전이지만 C#, js 및 golang을 사용할 준비가 되었습니다. 😊

내 예에서 나는 지금 배우고 있고 약간의 연습을 사용할 수 있는 언어인 golang으로 갈 것입니다 😅

우선, 코드에서 비트를 직접 비교할 수는 없습니다. 따라서 ip에는 음수 값이 없으므로 비트를 int 값 또는 보다 정확하게는 uint 값으로 구문 분석해야 합니다.

이것은 실제로 매우 쉽고 golang 놀이터here에서 복사할 준비가 되어 있습니다. 이 예에서는 단순성을 위해 이 함수에서 오류를 반환하지 않고 잘못된 ip 문자열이 삽입된 경우 직접 apanic를 수행합니다.

func Ip2long(ipAddr string) (uint32) {
  ip := net.ParseIP(ipAddr)
  if ip == nil {
    panic("wrong ipAddr format")
  }
  ip = ip.To4()
  return binary.BigEndian.Uint32(ip)
}


다음으로 주어진 네트워크의 ip가 in인지 not in인지 bool 값을 반환하는 비교 또는 유효성 검사 함수가 필요합니다. 비트 단위& 연산은 return에서 수행되며 여기에서 ip와 시작 주소, 서브넷 마스크를 모두 사용하여 검증 비트(단위로)를 생성한 다음 서로 비교하는 것을 볼 수 있습니다.

func IsInSubnet(ip string, startAddress string, mask string) bool {
  uIntIp :=  Ip2long(ip)
  uIntStartAdress := Ip2long(startAddress)
  uIntMask := Ip2long(mask)
  return (uIntIp & uIntMask) == (uIntStartAdress & uIntMask)  
}


놀기 위해 사용할 수 있는 모든 것:

package main

import (
    "encoding/binary"
    "fmt"
    "net"
)

func main() {
    mask := "255.255.255.192"
    startAddress := "192.168.50.65"
    ip1 := "192.168.50.20"
    ip2 := "192.168.50.80"

    fmt.Println("IP1 Result: ", IsInSubnet(ip1, startAddress, mask))
    fmt.Println("IP2 Result: ", IsInSubnet(ip2, startAddress, mask))
}

func IsInSubnet(ip string, startAddress string, mask string) bool {
    uIntIp := Ip2long(ip)
    uIntStartAdress := Ip2long(startAddress)
    uIntMask := Ip2long(mask)
    return (uIntIp & uIntMask) == (uIntStartAdress & uIntMask)
}

func Ip2long(ipAddr string) uint32 {
    ip := net.ParseIP(ipAddr)
    if ip == nil {
        panic("wrong ipAddr format")
    }
    ip = ip.To4()
    return binary.BigEndian.Uint32(ip)
}



즐겁고 좋은 하루 보내세요 🙂!

좋은 웹페이지 즐겨찾기