때로는 사용자가 시스템에 액세스할 수 있는지 확인하기 위해 특정 IP 주소가 네트워크 세그먼트에 속하는지 여부를 확인해야 합니다.
예를 들어, 사용자가 로그인한 IP는 218.6.7.7이고 우리 프로그램은 그가 네트워크 세그먼트 218.6.0.0/16에 속하는지 여부를 결정해야 합니다(여기서 /16은 새 서브넷 마스크의 표현으로 255.255.0.0과 동일함). .
이러한 기능을 달성하기 위해 현재 널리 사용되는 알고리즘은 218.6.0.0 및 218.6.7.7을 256을 기준으로 십진수로 변환하고 비교하는 것입니다. 예를 들어 먼저 218.6.0.0 및 218.6.255.255의 십진수를 계산합니다: 218×256×256. ×256+6×256×256=3657826304, 218×256×256×256+6×256×256+255×256×256+255=3657891839. 그런 다음 218.6.7.7의 소수를 계산합니다: 218×256×256×256+6×256×256+7×256+7=3657828103. 그리고 마지막으로 3657828103이 3657826304보다 크거나 같고 3657891839보다 작거나 같은지 비교합니다. . 하지만 분명히 문제가 있습니다. 계산량이 매우 크고 값도 매우 큽니다. IP 주소가 61로 시작하면 괜찮습니다. 218로 시작하면 데이터 오버플로 및 오류가 발생합니다.
실제로 IP가 특정 네트워크 세그먼트에 속하는지 비교하는 가장 좋은 방법은 IP와 네트워크 세그먼트를 32비트 바이너리로 변환한 다음 해당 네트워크 부분이 ASP 자체에 비트 연산이 없는지 비교하는 것입니다. 함수를 구현해야 하므로 다음과 같이 수동으로만 구현할 수 있습니다.
'10진수를 2진수 문자열로 변환
함수 dec2bin(octNumber)
vara=octNumber
하다
dec2bin=cstr(vara mod 2) & dec2bin
바라=바라 2
vara=0이 될 때까지 반복
end function
'2진 문자열을 8비트로 채움
함수 패드(str)
pad=right("00000000" & str,8)
end function
'IP 주소인지 확인
함수 isIp(ipad)
isIp=거짓
oReg=new RegExp 설정
oReg.IgnoreCase=true
oReg.global=true
oReg.Pattern="(d{1,4}.d{1,4}.d{1,4}.d{1,4})|(d{1,4} .d{1,4}.d{1,4}.d{1,4}/d{1,2})"
oReg.test(ipadd)이면 isIp=true
oReg=아무것도 설정하지 않음
end function
'여기서 UserIP는 우리가 감지하려는 IP입니다.
'NetIP는 감지할 네트워크 세그먼트 또는 특정 IP입니다. xxx.xxx.xxx.xxx/N을 사용하여 네트워크 세그먼트를 나타냅니다. 여기서 N은 서브넷 마스크 자릿수를 나타냅니다.
'참고로 이 프로그램은 Global Wanwei의 오리지널 프로그램이므로 재인쇄를 원하실 경우 출처정보를 남겨두시기 바랍니다. 감사합니다.
'프로그래밍: 도메인 이름 등록 및 가상 호스팅 서비스 전문 Global Wanwei
'웹사이트: http://www.netInter.cn
'위 정보는 기사 텍스트의 필수적인 부분이므로 이 기사를 다시 인쇄하려면 위 정보를 유지해야 합니다.
check_ip(UserIp,NetIP)
현재ip=UserIp
collection_ips=split(iplist,",") '네트워크를 포인트별로 4개의 세그먼트로 나눕니다.
check_ip=false '초기 함수 값, false는 IP가 이 네트워크 세그먼트에 없다고 가정합니다.
NetIP=트림(NetIP)
slashPos=inStr(NetIP,"/")
if slashPos=0 then '네트워크 세그먼트에 / 기호가 포함되어 있지 않고 IP일 뿐이므로 문자열을 비교하여 동일한지 확인하세요.
NetIP=currentip인 경우
check_ip=true 'check_ip=true는 IP가 동일함을 의미합니다.
종료 기능
종료하면
또 다른
netRang=mid(NetIP,slashPos+1) '다음의 숫자를 얻습니다 /
if not isNumeric(netRang) then '/다음에 숫자가 없으면 형식이 올바르지 않습니다.
종료 기능
종료하면
netRang=cint(netRang) '문자를 숫자로 변환
netRang>31이면
종료 기능 '/' 뒤의 숫자는 32자리를 초과할 수 없습니다.
종료하면
ipsets=split(currentip,".") '사용자 IP를 점
C_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets( 2) ))) & pad(dec2bin(ipsets(3)))
'위 줄은 사용자 IP 주소를 해당하는 32자 길이의 바이너리로 수동으로 변환하는 것입니다.
ipsets=split(NetIP,".") '위 프로세스에 따라 네트워크 세그먼트 IP를 32자 길이의 바이너리로 변환합니다.
sPos=instr(ipsets(3),"/") '마지막 형식은 숫자/숫자여야 합니다.
sPos=0이면
종료 기능
종료하면
ipsets(3)=left(ipsets(3),sPos-1) '마지막/이전 번호를 가져옵니다.
S_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
'32자 길이의 바이너리로 변환합니다.
if left(C_IP_BIN,netRang) = left(S_IP_BIN,netRang) then '네트워크 세그먼트가 동일한지 비교하여 사용자의 IP가 특정 네트워크 세그먼트에 속하는지 여부를 확인할 수 있습니다.
check_ip=true
종료하면
종료하면
End 함수
적용 예:
61.139.1.1이 네트워크 세그먼트 61.139.0.0/16(255.255.0.0)에 있는지 확인하려면 다음과 같이 간단히 이 함수를 사용하면 됩니다.
if check_ip("61.139.1.1","61.139 .0.0/16")
Response.write "동일한 네트워크 세그먼트"
또 다른
Response.write "동일한 네트워크 세그먼트가 아닙니다"
종료하면