我一直在测试一些代码,这些代码可以阻止来自特定国家/地区的用户的广告和视频。这不是什么新鲜事,当然不应该很难做到,但我无法解决它与IPv6地址一起工作,因为我不知道如何处理这些。我使用的数据库http://db-ip.com/db/最初看起来像这样:
将两个IP列值转换为二进制并将所有内容移动到新表后,我有:
这是测试代码(当我将其整理出来时,我将使用cfc和存储过程代替):
<!--- manualy change IPs to check if the code works --->
<cfset ipaddress="1.0.127.255">
<cfset ipToArray = listToArray(ipaddress,".")>
<cfset ipBinary= (ipToArray[1] * (256)^3) + (ipToArray[2] * (256)^2) + (ipToArray[3] * 256) + ipToArray[4]>
<cfquery name="getCountry" datasource="mydatabase">
SELECT country
FROM dbip_lookup
WHERE #ipBinary# >= bin1 AND #ipBinary# <= bin2
</cfquery>
<cfoutput>#getCountry.country#</cfoutput>
正如您所看到的,没有什么太可能只是一个适用于IPv4的简单测试代码:) 我应该以某种方式将IPv6转换为二进制以使其工作吗?如果是这样,该怎么做或是否有其他方法来实现相同的功能?我真的不知道从哪里开始:(
编辑 - 逐步过程
使用网站代码创建数据库表(csv文件中不存在addr_type,因此我删除了列以便能够正确导入csv)
CREATE TABLE `dbip_lookup` (
`ip_start` varbinary(16) NOT NULL,
`ip_end` varbinary(16) NOT NULL,
`country` char(2) NOT NULL,
PRIMARY KEY (`ip_start`)
);
成功创建表后尝试填充数据
LOAD DATA INFILE 'C:/dbip-country.csv'
INTO TABLE dbip_lookup2
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
未能抛出以下错误消息“10:07:52 LOAD DATA INFILE'C:/dbip-country.csv'INTO TABLE dbip_lookup2 FIELDS TERMINATED BY','enclOSED by'''LINES INATED IN'\ r \ n '错误代码:1406。第158131行19.641秒列'ip_end'的数据太长 “158131行是IPv6地址的起始位置。
将两个varbinary列修改为(50)mysql成功创建并使用上面的代码填充表。
你的一些简化的cfm代码(它无论如何都不起作用)
<cfset InetAddress = createObject("java", "java.net.InetAddress")>
<cfset addrStart = InetAddress.getByName("2001:0db8:85a3:08d3:1319:8a2e:0370:7344").getAddress()>
<!--- for MySQL. Use TOP 1 for SQL Server --->
<cfquery name="qResult">
select country from dbip_lookup2
where ip_start <= "#addrStart#"
</cfquery>
<cfoutput>#qResult.country#</cfoutput>
触发自定义错误处理程序:
第43行是WHERE子句开始的地方
答案 0 :(得分:0)
通过查看PHP中的sample look up code,可以将逻辑移植到这样的内容,以便在CF中查找IPv6,而无需转换为新表:
<cfset InetAddress = createObject("java", "java.net.InetAddress")>
<cfset addrStart =
InetAddress.getByName("2001:0db8:85a3:08d3:1319:8a2e:0370:7344").getAddress()>
<!--- for MySQL. Use TOP 1 for SQL Server --->
<cfquery name="qResult">
select * from dbip_lookup
where addr_type = 'ipv6' and
ip_start <= <cfqueryparam value="#addrStart#" type="CF_SQL_VARBINARY">
order by ip_start desc limit 1
</cfquery>
我没有试过这个,希望你能让它发挥作用。
修改强>
您必须对<cfqueryparam>
使用addrStart
,因为CF无法将二进制数组转换为##
的字符串并以SQL身份发送。如果仍然无效,请考虑使用BinaryEncode()
转换为十六进制。