PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Определете държавата от IP - IPv6

Вярвам, че намерих решението. Това включва първо модифициране на данните и след това известно масажиране на входа. Ето какво проработи.

Първо, данните трябва да бъдат конвертирани, така че всички адреси да са пълни, без съкращения, с премахнати разделители точка и запетая. Примерните данни, показани в моя въпрос, се преобразуват в:

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

Това е, което се съхранява в базата данни.

Следващата стъпка беше преобразуването на IP адреса, получен в кода, в същия формат. Това се прави в PHP със следния код (да приемем, че $ip_address е входящият IPv6 адрес):

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

Сега променлива $ip_adress ще съдържа пълния IPv6 адрес, например

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

и така нататък.

Сега можете просто да сравните този пълен адрес с диапазоните в базата данни. Добавих втора функция към базата данни за работа с IPv6 адреси, която изглежда така:

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;

И накрая, в моя php код добавих кода, който извиква една или друга функция на Postgres въз основа на входния ip_address.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Поправяне на повредена база данни postgresql

  2. Ansible обича PostgreSQL

  3. Изброяване на дяловете на таблицата в таблицата на Postgres

  4. Postgresql формат на датата

  5. Еквивалент на Group_concat в postgresql 8.2.11