使用 Classic ASP 检查地理位置数据库
Check geolocation database using Classic ASP
我有一个用于确定国家/地区的 IP 地址范围数据库,但需要一个用 Classic ASP 编写的函数来找到用户 IP 地址适合的范围.
例如数据库行如下:
102.23.25.0 | 102.24.0.0 | US
如果 IP 地址是 102.23.25.203,我该如何找到匹配项?
这似乎比 VB 更像是一个数据库问题。像下面这样的查询应该可以做到。
select locationName
from IPLocationTable
where @inputIP >= IPStartRange
and @inputIP <= IPEndRange
您使用标准 ADO 数据访问发出此查询,例如
sql = "put select statement here"
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.ConnectionTimeout = TIMEOUT
Conn.Open CONNECTIONSTRING
Set rs = Server.CreateObject("ADODB.Recordset")
set rs.ActiveConnection = Conn
rs.Open sql,,adOpenForwardOnly,adLockReadOnly,adCmdText
set countryName = rs("locationName")
rs.close
conn.close
这里有一个测试来说明我的意思。请注意,您必须稍微修改 IP 以添加前导零。
CREATE TABLE IPLocationTable(
[StartIP] [varchar](50) NULL,
[EndIP] [varchar](50) NULL,
[Location] [varchar](50) NULL
) ON [PRIMARY]
go
insert IPLocationTable(StartIP, EndIP, Location) values ('192.168.001.001', '192.168.001.255', 'Location1')
insert IPLocationTable(StartIP, EndIP, Location) values ('192.168.002.001', '192.168.002.255', 'Location2')
insert IPLocationTable(StartIP, EndIP, Location) values ('192.168.003.001', '192.168.004.255', 'Location3')
insert IPLocationTable(StartIP, EndIP, Location) values ('192.168.005.001', '192.168.006.255', 'Location4')
insert IPLocationTable(StartIP, EndIP, Location) values ('195.168.001.001', '196.168.001.255', 'Location5')
insert IPLocationTable(StartIP, EndIP, Location) values ('197.169.001.001', '198.169.001.255', 'Location6')
go
declare @myIP varchar(20)
set @myIP = '192.168.001.150'
select location from IPLocationTable where @myIP >= StartIP and @myIP <= endIP
set @myIP = '192.168.002.150'
select location from IPLocationTable where @myIP >= StartIP and @myIP <= endIP
set @myIP = '196.168.001.150'
select location from IPLocationTable where @myIP >= StartIP and @myIP <= endIP
您可以使用Request.ServerVariables("REMOTE_ADDR")
获取用户的IP地址,然后简单地测试地址段...
Function TestIp(testAddr, loIp, hiIp)
Dim host, rLo, rHi, fail, i
host = Split(testAddr, ".")
fail = False
rLo = Split(loIp, ".")
rHi = Split(hiIp, ".")
For i = 0 To 3
'If one of the host values falls outside the range then it's all over...
fail = CInt(host(i))<CInt(rLo(i)) Or CInt(host(i))>CInt(rHi(i))
If fail Then Exit For
Next 'i
TestIp = fail
End If
SQL版本
我们知道一个事实,即每个 IP 都可以分成四个。执行此操作的命令是 CHARINDEX
and SUBSTRING
的组合。只需将测试值分解为四个并对低值和高值执行相同的操作,然后针对各自的高值和低值测试每个字节。
这是一个函数,我花了几分钟才写出来,就是为了做到这一点:
/*
getIpQuad
Returns the required quad of an IP address.
Usage:
SET @q2 = getIpQuad('127.0.0.1', 2)
Parameters:
@ip (STRING) - The IP address
@quad (TINYINT) - The quad to retrieve (zero based)
*/
CREATE FUNCTION [dbo].[getIpQuad]
(@ip AS VARCHAR(15),
@quad AS TINYINT)
RETURNS TINYINT AS
BEGIN
DECLARE @i AS TINYINT
DECLARE @s AS TINYINT
DECLARE @e AS TINYINT
DECLARE @v AS VARCHAR(3)
SET @s = 0
SET @e = 0
SET @i = 0
WHILE @i<=@quad
BEGIN
SET @e = CHARINDEX('.', @ip, @s+1)
IF @e = 0 AND @s>1 SET @e = LEN(@ip)
SET @v = SUBSTRING(@ip, @s+1, @e-@s)
SET @s = @e
SET @i = @i + 1
END
RETURN (CAST(@v AS TINYINT))
END
注意:我没有包括任何边界检查,它依赖于你知道你在做什么的事实。
我使用 MaxMind CSV 数据库将其导入 MS-SQL。然后写了一个简单的经典ASP例程来获取国家代码。
strCheckIPnumber = Request.ServerVariables("REMOTE_ADDR")
if strCheckIPnumber <> "" then
strGeoArray = Split(strCheckIPnumber, ".")
For i=0 to UBound(strGeoArray)
Next
strGeo1 = strGeoArray(0)
strGeo2 = strGeoArray(1)
strGeo3 = strGeoArray(2)
strGeo4 = strGeoArray(3)
strGeoNumber = strGeo1 * 16777216 + strGeo2 * 65536 + strGeo3 * 256 + strGeo4
'response.write"GeoNumber = " & strGeoNumber & "<br>"
SQLGeo = "SELECT Country FROM GeoLocation Where GeoLocation.StartNum <= '" & strGeoNumber & "' and GeoLocation.EndNum >= '" & strGeoNumber & "' "
Set rsGeo = dbConnection.Execute(SQLGeo)
if NOT rsGeo.EOF then
strGeoCountry = rsGeo("Country").value
end if
rsGeo.Close
Set rsGeo = Nothing
response.write"GeoCountry = " & strGeoCountry & "<br>"
end if
我有一个用于确定国家/地区的 IP 地址范围数据库,但需要一个用 Classic ASP 编写的函数来找到用户 IP 地址适合的范围.
例如数据库行如下:
102.23.25.0 | 102.24.0.0 | US
如果 IP 地址是 102.23.25.203,我该如何找到匹配项?
这似乎比 VB 更像是一个数据库问题。像下面这样的查询应该可以做到。
select locationName
from IPLocationTable
where @inputIP >= IPStartRange
and @inputIP <= IPEndRange
您使用标准 ADO 数据访问发出此查询,例如
sql = "put select statement here"
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.ConnectionTimeout = TIMEOUT
Conn.Open CONNECTIONSTRING
Set rs = Server.CreateObject("ADODB.Recordset")
set rs.ActiveConnection = Conn
rs.Open sql,,adOpenForwardOnly,adLockReadOnly,adCmdText
set countryName = rs("locationName")
rs.close
conn.close
这里有一个测试来说明我的意思。请注意,您必须稍微修改 IP 以添加前导零。
CREATE TABLE IPLocationTable(
[StartIP] [varchar](50) NULL,
[EndIP] [varchar](50) NULL,
[Location] [varchar](50) NULL
) ON [PRIMARY]
go
insert IPLocationTable(StartIP, EndIP, Location) values ('192.168.001.001', '192.168.001.255', 'Location1')
insert IPLocationTable(StartIP, EndIP, Location) values ('192.168.002.001', '192.168.002.255', 'Location2')
insert IPLocationTable(StartIP, EndIP, Location) values ('192.168.003.001', '192.168.004.255', 'Location3')
insert IPLocationTable(StartIP, EndIP, Location) values ('192.168.005.001', '192.168.006.255', 'Location4')
insert IPLocationTable(StartIP, EndIP, Location) values ('195.168.001.001', '196.168.001.255', 'Location5')
insert IPLocationTable(StartIP, EndIP, Location) values ('197.169.001.001', '198.169.001.255', 'Location6')
go
declare @myIP varchar(20)
set @myIP = '192.168.001.150'
select location from IPLocationTable where @myIP >= StartIP and @myIP <= endIP
set @myIP = '192.168.002.150'
select location from IPLocationTable where @myIP >= StartIP and @myIP <= endIP
set @myIP = '196.168.001.150'
select location from IPLocationTable where @myIP >= StartIP and @myIP <= endIP
您可以使用Request.ServerVariables("REMOTE_ADDR")
获取用户的IP地址,然后简单地测试地址段...
Function TestIp(testAddr, loIp, hiIp)
Dim host, rLo, rHi, fail, i
host = Split(testAddr, ".")
fail = False
rLo = Split(loIp, ".")
rHi = Split(hiIp, ".")
For i = 0 To 3
'If one of the host values falls outside the range then it's all over...
fail = CInt(host(i))<CInt(rLo(i)) Or CInt(host(i))>CInt(rHi(i))
If fail Then Exit For
Next 'i
TestIp = fail
End If
SQL版本
我们知道一个事实,即每个 IP 都可以分成四个。执行此操作的命令是 CHARINDEX
and SUBSTRING
的组合。只需将测试值分解为四个并对低值和高值执行相同的操作,然后针对各自的高值和低值测试每个字节。
这是一个函数,我花了几分钟才写出来,就是为了做到这一点:
/*
getIpQuad
Returns the required quad of an IP address.
Usage:
SET @q2 = getIpQuad('127.0.0.1', 2)
Parameters:
@ip (STRING) - The IP address
@quad (TINYINT) - The quad to retrieve (zero based)
*/
CREATE FUNCTION [dbo].[getIpQuad]
(@ip AS VARCHAR(15),
@quad AS TINYINT)
RETURNS TINYINT AS
BEGIN
DECLARE @i AS TINYINT
DECLARE @s AS TINYINT
DECLARE @e AS TINYINT
DECLARE @v AS VARCHAR(3)
SET @s = 0
SET @e = 0
SET @i = 0
WHILE @i<=@quad
BEGIN
SET @e = CHARINDEX('.', @ip, @s+1)
IF @e = 0 AND @s>1 SET @e = LEN(@ip)
SET @v = SUBSTRING(@ip, @s+1, @e-@s)
SET @s = @e
SET @i = @i + 1
END
RETURN (CAST(@v AS TINYINT))
END
注意:我没有包括任何边界检查,它依赖于你知道你在做什么的事实。
我使用 MaxMind CSV 数据库将其导入 MS-SQL。然后写了一个简单的经典ASP例程来获取国家代码。
strCheckIPnumber = Request.ServerVariables("REMOTE_ADDR")
if strCheckIPnumber <> "" then
strGeoArray = Split(strCheckIPnumber, ".")
For i=0 to UBound(strGeoArray)
Next
strGeo1 = strGeoArray(0)
strGeo2 = strGeoArray(1)
strGeo3 = strGeoArray(2)
strGeo4 = strGeoArray(3)
strGeoNumber = strGeo1 * 16777216 + strGeo2 * 65536 + strGeo3 * 256 + strGeo4
'response.write"GeoNumber = " & strGeoNumber & "<br>"
SQLGeo = "SELECT Country FROM GeoLocation Where GeoLocation.StartNum <= '" & strGeoNumber & "' and GeoLocation.EndNum >= '" & strGeoNumber & "' "
Set rsGeo = dbConnection.Execute(SQLGeo)
if NOT rsGeo.EOF then
strGeoCountry = rsGeo("Country").value
end if
rsGeo.Close
Set rsGeo = Nothing
response.write"GeoCountry = " & strGeoCountry & "<br>"
end if