1

特定の国のユーザーに対して広告や動画をブロックできるようにするコードをいくつかテストしています。これは新しいことではなく、確かに難しいことではありませんが、IPv6 アドレスを処理する方法がわからないため、IPv6 アドレスで動作するように整理することはできません。私はこのデータベースhttp://db-ip.com/db/を使用します。これは最初は次のようになります。

ここに画像の説明を入力

2 つの 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 をバイナリに変換して動作させる必要がありますか? もしそうなら、それを行う方法、または同じ機能を実現する他の方法はありますか? 私は本当にどこから始めればいいのかわからない:(

編集 - ステップバイステッププロセス

Web サイトのコードを使用して DB テーブルを作成します (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 は上記のコードでテーブルを正常に作成および設定しました。

ここに画像の説明を入力

少し単純化された 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 句が開始する場所です。

4

1 に答える 1

0

PHP のルックアップ コードのサンプルを調べると、新しいテーブルに変換することなく、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>

私はこれを試していませんが、うまくいくことを願っています。

編集

CF はバイナリ配列を文字列に変換できず、SQL として送信できないため、 <cfqueryparam>for を使用する必要があります。それでもうまくいかない場合は、 を使用して 16 進数に変換することを検討してください。addrStart##BinaryEncode()

于 2013-10-16T18:42:10.430 に答える