Как преобразовать IPv6 из двоичного файла для устройства хранения данных в MySQL

Строковый объект Java имеет format метод (с 1,5), но никакой join метод.

Для получения набора полезных Строковых служебных методов, не уже включенных, Вы могли использовать org.apache.commons.lang. StringUtils.

16
задан Community 23 May 2017 в 12:09
поделиться

2 ответа

Вот функции, которые я сейчас использую для преобразования IP-адресов из и в формат DECIMAL (39,0). Они называются inet_ptod и inet_dtop для «представления в десятичном формате» и «десятичного в представление». Для него требуется поддержка IPv6 и bcmath в PHP.

/**
 * Convert an IP address from presentation to decimal(39,0) format suitable for storage in MySQL
 *
 * @param string $ip_address An IP address in IPv4, IPv6 or decimal notation
 * @return string The IP address in decimal notation
 */
function inet_ptod($ip_address)
{
    // IPv4 address
    if (strpos($ip_address, ':') === false && strpos($ip_address, '.') !== false) {
        $ip_address = '::' . $ip_address;
    }

    // IPv6 address
    if (strpos($ip_address, ':') !== false) {
        $network = inet_pton($ip_address);
        $parts = unpack('N*', $network);

        foreach ($parts as &$part) {
            if ($part < 0) {
                $part = bcadd((string) $part, '4294967296');
            }

            if (!is_string($part)) {
                $part = (string) $part;
            }
        }

        $decimal = $parts[4];
        $decimal = bcadd($decimal, bcmul($parts[3], '4294967296'));
        $decimal = bcadd($decimal, bcmul($parts[2], '18446744073709551616'));
        $decimal = bcadd($decimal, bcmul($parts[1], '79228162514264337593543950336'));

        return $decimal;
    }

    // Decimal address
    return $ip_address;
}

/**
 * Convert an IP address from decimal format to presentation format
 *
 * @param string $decimal An IP address in IPv4, IPv6 or decimal notation
 * @return string The IP address in presentation format
 */
function inet_dtop($decimal)
{
    // IPv4 or IPv6 format
    if (strpos($decimal, ':') !== false || strpos($decimal, '.') !== false) {
        return $decimal;
    }

    // Decimal format
    $parts = array();
    $parts[1] = bcdiv($decimal, '79228162514264337593543950336', 0);
    $decimal = bcsub($decimal, bcmul($parts[1], '79228162514264337593543950336'));
    $parts[2] = bcdiv($decimal, '18446744073709551616', 0);
    $decimal = bcsub($decimal, bcmul($parts[2], '18446744073709551616'));
    $parts[3] = bcdiv($decimal, '4294967296', 0);
    $decimal = bcsub($decimal, bcmul($parts[3], '4294967296'));
    $parts[4] = $decimal;

    foreach ($parts as &$part) {
        if (bccomp($part, '2147483647') == 1) {
            $part = bcsub($part, '4294967296');
        }

        $part = (int) $part;
    }

    $network = pack('N4', $parts[1], $parts[2], $parts[3], $parts[4]);
    $ip_address = inet_ntop($network);

    // Turn IPv6 to IPv4 if it's IPv4
    if (preg_match('/^::\d+.\d+.\d+.\d+$/', $ip_address)) {
        return substr($ip_address, 2);
    }

    return $ip_address;
}
19
ответ дан 30 November 2019 в 15:41
поделиться

Мы выбрали ПЕРЕМЕННУЮ (16) вместо столбца и используйте inet_pton () и inet_ntop () для преобразования:

https://github.com/skion/mysql-udf-ipv6

Функции могут быть загружены в работающий сервер MySQL и предоставят вам INET6_NTOP и INET6_PTON в SQL, как и знакомые INET_NTOA и INET_ATON функции для IPv4.

Изменить: теперь в MySQL есть совместимые функции, только с разными именами . Используйте указанное выше, только если вы используете MySQL до 5.6 и ищете удобный способ обновления в будущем.

31
ответ дан 30 November 2019 в 15:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: