Запрос MySQL для преобразования CIDR в диапазон IP

2 PHP Avenger [2016-02-22 22:43:00]

У меня есть таблица, которая содержит столбец как значения CIDR, такие как 1.0.85.128/25, у меня есть еще два столбца (start_ip_range и end_ip_range), я хочу заполнить эти столбцы из столбца FROM CIDR

Код Java может выглядеть следующим образом:

String[] parts = cidr.split("/");
String ip = parts[0];
int prefix;
if (parts.length < 2) {
    prefix = 0;
} else {
    prefix = Integer.parseInt(parts[1]);
}

String[] ipParts = ip.split("\\.");
int address = ((new Integer(ipParts[0]) << 24) & 0xFF000000) 
    | ((new Integer(ipParts[1]) << 16) & 0xFF0000) 
    | ((new Integer(ipParts[2]) << 8) & 0xFF00) 
    | (new Integer(ipParts[3]) & 0xFF);
int mask = (-1) << (32 - prefix);
int start = address & mask;
int end = start + (~mask);

Как это можно преобразовать в MySql Query.

mysql cidr


1 ответ


6 Решение Bernd Buffen [2016-02-23 00:24:00]

Вы можете его конвертировать так

запрос

SELECT
  INET_NTOA(INET_ATON( SUBSTRING_INDEX(val, '/', 1)) 
   & 0xffffffff ^ ((0x1 << ( 32 - SUBSTRING_INDEX(val, '/', -1))  ) -1 )) from_ip,
  INET_NTOA(INET_ATON( SUBSTRING_INDEX(val, '/', 1)) 
   | ((0x100000000 >> SUBSTRING_INDEX(val, '/', -1) ) -1 )) to_ip
FROM cidr;

Пример таблицы

CREATE TABLE 'cidr' (
  'id' int(11) unsigned NOT NULL AUTO_INCREMENT,
  'val' varchar(32) DEFAULT NULL,
  PRIMARY KEY ('id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO 'cidr' ('id', 'val')
VALUES
    (1, '192.168.2.12/24'),
    (2, '192.168.2.12/25'),
    (3, '1.0.85.128/25'),
    (4, '192.168.2.12/32');

Или вы можете использовать его в виртуальных столбцах. Таким образом, вы получаете прямое значение.

Виртуальные поля

CREATE TABLE 'cidr1' (
  'id' INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  'val' VARCHAR(32) DEFAULT NULL,
  'from_ip' VARCHAR(15) AS ( INET_NTOA(INET_ATON( SUBSTRING_INDEX(val, '/', 1)) & 0xffffffff ^ ((0x1 << ( 32 - SUBSTRING_INDEX(val, '/', -1))  ) -1 ))) PERSISTENT ,
  'to_ip' VARCHAR(15)  AS ( INET_NTOA(INET_ATON( SUBSTRING_INDEX(val, '/', 1)) | ((0x100000000 >> SUBSTRING_INDEX(val, '/', -1) ) -1 ))) PERSISTENT ,
  PRIMARY KEY ('id')
) ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO 'cidr1' ('id', 'val')
VALUES
    (1, '192.168.2.12/24'),
    (2, '192.168.2.12/25'),
    (3, '1.0.85.128/25'),
    (4, '192.168.2.12/32');


MariaDB []> select * from cidr1;
+----+-----------------+--------------+---------------+
| id | val             | from_ip      | to_ip         |
+----+-----------------+--------------+---------------+
|  1 | 192.168.2.12/24 | 192.168.2.0  | 192.168.2.255 |
|  2 | 192.168.2.12/25 | 192.168.2.0  | 192.168.2.127 |
|  3 | 1.0.85.128/25   | 1.0.85.128   | 1.0.85.255    |
|  4 | 192.168.2.12/32 | 192.168.2.12 | 192.168.2.12  |
+----+-----------------+--------------+---------------+
4 rows in set (0.00 sec)

MariaDB []>