# Bitwise AND for Large Numbers in Traditional ASP

Once in a while (like today) I have to go back and do something in traditional ASP (Active Server Pages). That’s when I realize how nice .NET is, with typed data and all those framework methods. Something seemingly trivial, like figuring out if an IP address is part of a network, turns out to be quite difficult. The normal approach here would be to convert the IP address, network and subnet into integers, do a bitwise AND of the two items, and then compare the result. Unfortunately, the “AND” operator in ASP only works with integers and “Long” integers (up to 2^31 or 2,147,483,647), and the integer representation of 255.255.255.0 is 4,294,901,760. Uh oh. So, I came up with a double-precision AND function which splits the double value into “high” and “low” chunks (basically, the part below 2^31 and the part above), performs a bitwise AND on the chunks, and then shifts the bits back into place and reassembles a Double value from this. This should be viable for the bits left of the decimal up to about 4.6E+18. At the very least, it’s working for the IP address example.

```function DoubleAnd (d1,d2)
' bitwise AND for values potentially greater than the Long limit (2147483647)
dim d1low, d1high, d2low, d2high, lowand, highand
d1high = fix(d1 / (2^31))
d1low = fix(d1 - d1high * (2^31))
d2high = fix(d2 / (2^31))
d2low = fix(d2 - d2high * (2^31))
lowand = d1low and d2low
highand = d1high and d2high
DoubleAnd = highand * (2^31) + lowand
end function
```

It’s called like this:

```if (DoubleAnd(ipint,subnetint)) = (DoubleAnd(networkint,subnetint)) then
response.write ("IP is on network")
else
response.Write ("IP is NOT on network")
end if
```

Note that I’m ANDing both the ip address and the network address. This shouldn’t technically be necessary, but it helps in cases where the user types in another IP address on the network instead of the network address (e.g. 192.168.1.1 instead of 192.168.1.0).

Here are the helper functions required for the conversions:

```function IsValidIpAddress (IP)
dim aGroups, i, j
aGroups = split(IP,".")
if ubound(aGroups) <> 3 then
exit function
end if
for i = 0 to ubound(aGroups)
j = aGroups(i)
if not isNumeric (j) then
exit function
end if
if j < 0 or j > 255 then
exit function
end if
next
end function