2013-10-16 72 views
1

我一直在測試一些代碼,以允許我阻止來自特定國家的用戶的廣告和視頻。這不是什麼新東西,當然不應該很難做到,但是我無法將它整理到IPv6地址,因爲我不知道如何處理這些地址。我使用這個數據庫http://db-ip.com/db/最初看起來是這樣的:通過IP獲取國家/地區位置(IPv4,IPv6)

enter image description here

一切將兩個IP列值二進制和移動到新表後,我有這樣的:

enter image description here

這裏是測試代碼(當我對它進行分類時,我將使用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轉換爲二進制文件使其工作?如果是這樣,如何做到這一點或有其他方式來實現相同的功能?我真的不知道從哪裏開始:(

編輯 - 循序漸進的過程

創建數據庫表與網站代碼(ADDR_TYPE不csv文件存在,所以我刪除的列,以便能夠正確導入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 TERMINATED BY'\ r \ n'錯誤代碼:1406.行158131行'ip_end'的數據太長19.641秒 「158131行是IPv6地址開始的地方。

將兩個varbinary列都修改爲(50)mysql成功創建並使用上面的代碼填充表。

enter image description here

你有點簡化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> 

觸發自定義錯誤處理程序:

enter image description here

線43就是WHERE子句開始

+0

http://db-ip.com/db/確實支持IPv6,DB中有很多:) – user2595617

回答

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()轉換爲十六進制。

+0

不知道如何獲得基於IPv4的國家/地區信息,除非另有兩列被分配!如何計算範圍內? – user2595617

+0

我也檢查過你的代碼,並得到「ByteArray對象不能轉換爲字符串」這可能是因爲我已經將varbinary更改爲varchar ...在網站上創建表的代碼不起作用! – user2595617

+0

只是按照原樣使用數據庫,不要更改它,查找代碼應該按預期工作。如果您使用MSSQL,請使用位於http://db-ip.com/db/#external的ZORAN DB-IP導入程序 – Henry

相關問題