我有一个用于确定国家/地区的IP地址范围数据库,但需要一个用经典ASP 编写的函数来查找用户IP地址所适合的范围。
例如,数据库行类似于:
102.23.25.0 | 102.24.0.0 | US
因此,如果IP地址是102.23.25.203,我该如何找到匹配项?
答案 0 :(得分:0)
您可以使用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
和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
注意:我没有包含任何边界检查,它依赖于您知道自己在做什么这一事实。
答案 1 :(得分:0)
使用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
答案 2 :(得分:-1)
这似乎比VB更像是一个DB问题。像下面这样的查询应该这样做。
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