Sometimes we need to determine whether a certain IP address belongs to a network segment to determine whether the user can access the system.
For example, the user's logged-in IP is 218.6.7.7, and our program must determine whether he belongs to the network segment 218.6.0.0/16 (where /16 is the representation of the new subnet mask, equivalent to 255.255.0.0).
To achieve such a function, the popular algorithm now is to convert 218.6.0.0 and 218.6.7.7 into decimal based on 256 and compare them. For example, first calculate the decimal of 218.6.0.0 and 218.6.255.255: 218× 256×256×256+6×256×256=3657826304, 218×256×256×256+6×256×256+255×256×256+255=3657891839. Then calculate the decimal of 218.6.7.7: 218×256×256×256+6×256×256+7×256+7=3657828103, and finally compare whether 3657828103 is greater than or equal to 3657826304 and less than or equal to 3657891839. But there is obviously a problem. The calculation amount is very large and the value is very large. If the IP address starts with 61, it is fine. If it starts with 218, this will cause data overflow and error.
In fact, the best way to compare whether an IP belongs to a certain network segment is to convert the IP and network segment into 32-bit binary, and then compare whether their network parts are the same. ASP itself does not have the bit operation function, so it is necessary to implement We can only implement this manually, as follows:
'Convert decimal to binary string
function dec2bin(octNumber)
vara=octNumber
do
dec2bin=cstr(vara mod 2) & dec2bin
vara=vara 2
loop until vara=0
end function
'Padding binary string to 8 bits
function pad(str)
pad=right("00000000" & str,8)
end function
'Determine whether it is an IP address
function isIp(ipadd)
isIp=false
set 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})"
if oReg.test(ipadd) then isIp=true
set oReg=nothing
end function
'where UserIP is the IP we want to detect
'NetIP is the network segment or a certain IP to be detected. Use xxx.xxx.xxx.xxx/N to represent the network segment, where N represents the number of subnet mask digits.
'Note, this program is an original program of Global Wanwei, so if you want to reprint it, please keep the source information, thank you.
'Programming: Global Wanwei, specializing in domain name registration and virtual hosting services
'Website: http://www.netInter.cn
'The above information is an integral part of the article text, so if you want to reprint this article, you must retain the above information.
Function check_ip(UserIp,NetIP)
currentip=UserIp
collection_ips=split(iplist,",") 'Split the network into 4 segments by points
check_ip=false 'Initial function value, false assumes that the IP is not in this network segment
NetIP=trim(NetIP)
slashPos=inStr(NetIP,"/")
if slashPos=0 then 'The network segment does not contain the / symbol, it is just an IP, so just compare the strings to see if they are the same.
if NetIP=currentip then
check_ip=true 'check_ip=true means the IPs are equal
exit function
end if
else
netRang=mid(NetIP,slashPos+1) 'Get the number after /
if not isNumeric(netRang) then '/It is not followed by a number, the format is incorrect
exit function
end if
netRang=cint(netRang) 'Convert characters to numbers
if netRang>31 then
The number after exit function '/ cannot exceed 32 digits
end if
ipsets=split(currentip,".") 'Divide the user IP into four segments by points
C_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2) ))) & pad(dec2bin(ipsets(3)))
'The above line is to manually convert the user IP address into a corresponding 32-character long binary
ipsets=split(NetIP,".") 'Follow the above process to convert the network segment IP into a 32-character long binary
sPos=instr(ipsets(3),"/") 'The last format should be numbers/digits
if sPos=0 then
exit function
end if
ipsets(3)=left(ipsets(3),sPos-1) 'Get the last/previous number
S_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
'Convert it to a 32 character long binary
if left(C_IP_BIN,netRang) = left(S_IP_BIN,netRang) then 'By comparing whether the network segments are the same, you can determine whether the user's IP belongs to a certain network segment.
check_ip=true
end if
end if
End function
application example:
To determine whether 61.139.1.1 is in the network segment 61.139.0.0/16 (255.255.0.0), you only need to simply use this function, such as:
if check_ip("61.139.1.1","61.139. 0.0/16") then
Response.write "same network segment"
else
Response.write "Not the same network segment"
end if