PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Określ kraj na podstawie adresu IP - IPv6

Wierzę, że znalazłem rozwiązanie. Polega na modyfikacji danych najpierw, a następnie masowaniu danych wejściowych. Oto, co zadziałało.

Najpierw dane muszą zostać przekonwertowane, aby wszystkie adresy były pełne, bez skracania, z usuniętymi separatorami średnikowymi. Przykładowe dane pokazane w moim pytaniu są konwertowane na:

 t_start                          | t_end                            | t_country_code
----------------------------------+----------------------------------+----------------
 00000000000000000000000000000000 | 00ffffffffffffffffffffffffffffff | ZZ
 01000000000000000000000000000000 | 01ffffffffffffffffffffffffffffff | ZZ
...
 20000000000000000000000000000000 | 2000ffffffffffffffffffffffffffff | ZZ
...
 20011200000000000000000000000000 | 20011200ffffffffffffffffffffffff | MX
...

To jest to, co jest przechowywane w bazie danych.

Kolejnym krokiem było przekonwertowanie adresu IP otrzymanego w kodzie na ten sam format. Odbywa się to w PHP za pomocą następującego kodu (załóżmy, że $ip_address to przychodzący adres IPv6):

$addr_bin = inet_pton($ip_address);                                                                                                              
$bytes = unpack('n*', $addr_bin);
$ip_address = implode('', array_map(function ($b) {return sprintf("%04x", $b); }, $bytes));

Teraz zmienna $ip_adress będzie zawierać pełny adres IPv6, na przykład

:: => 00000000000000000000000000000000
2001:1200::ab => 200112000000000000000000000000ab

i tak dalej.

Teraz możesz po prostu porównać ten pełny adres z zakresami w bazie danych. Do bazy danych dodałem drugą funkcję zajmującą się adresami IPv6, która wygląda tak:

CREATE OR REPLACE FUNCTION get_country_for_ipv6(character varying)
  RETURNS character varying AS
$BODY$
declare
    ip  ALIAS for $1;
    ccode   varchar;
begin
    select into ccode t_country_code from ipv6_to_country where addr between n_from and n_to limit 1;
    if ccode is null then
        ccode := '';
    end if;
    return ccode;
end;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

Wreszcie w moim kodzie php dodałem kod, który wywołuje jedną lub drugą funkcję Postgres na podstawie wejściowego adresu ip.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nie znaleziono pg_dump w szynach

  2. Seminarium internetowe :Nowe funkcje w PostgreSQL 11 [Kontynuacja]

  3. Znajdź zdania z dwoma słowami sąsiadującymi ze sobą w Pg

  4. Uzyskaj listę wszystkich używanych tabel w zapytaniu SELECT w Postgresql

  5. Sterownik PostgreSQL JDBC nie działa dla połączenia Heroku DB