PHP 和 JavaScript IPV6与数字之间的转换, Converted To IPv6 address

mac2025-06-22  10

项目中需把IPV6 转成数字 方便保存数据库,利于节省空间和加速查询。废话不多说贴代码: JavaScript: BigInteger.js

//ipv6 转38为数字 function ip2long6(ip_address) { var parts = []; ip_address.split(':').forEach(function(it) { var bin = parseInt(it, 16).toString(2); while (bin.length < 16) { bin = '0' + bin; } parts.push(bin); }); var bin = parts.join(''); //需要引入js文件,我会在附件贴上 return bigInt(bin, 2).toString(); } /** * 位数补偿 * @param dividend * @param divisor * @returns {{quotient: (string|*), remainder: *}} */ function divide(dividend, divisor) { var returnValue = ''; var remainder = 0; var currentDividend = 0, currentQuotient; dividend.split('').forEach(function(digit, index) { // use classical digit by digit division if (currentDividend !== 0) { currentDividend = currentDividend * 10; } currentDividend += parseInt(digit); if (currentDividend >= divisor) { currentQuotient = Math.floor(currentDividend / divisor); currentDividend -= currentQuotient * divisor; returnValue += currentQuotient.toString(); } else if (returnValue.length > 0) { returnValue += '0'; } if (index === dividend.length - 1) { remainder = currentDividend; } }); return { quotient: returnValue.length === 0 ? '0' : returnValue, remainder: remainder, }; } /** * 数字转ipv6 * @param input * @param base * @returns {string} */ function convertToIPv6(input, base) { base = base || 10; var blocks = []; var blockSize = Math.pow(2, 16); // 16 bit per block while (blocks.length < 8) { var divisionResult = divide(input, blockSize); // The remainder is the block value blocks.unshift(divisionResult.remainder.toString(base)); // The quotient will be used as dividend for the next block input = divisionResult.quotient; } return blocks.join(':'); }

PHP代码: 注:需要打开php.ini 里面的 extension=php_gmp.dll 如果没有dll 请自行下载。如果你是linux 请自行编译so

/** * IPV6 地址转换为整数 * @param $ipv6 * @return string * */ public function ip2long6($ipv6) { $ip_n = inet_pton($ipv6); $bits = 15; // 16 x 8 bit = 128bit $ipv6long = ''; while ($bits >= 0) { $bin = sprintf("%08b", (ord($ip_n[$bits]))); $ipv6long = $bin . $ipv6long; $bits--; } return gmp_strval(gmp_init($ipv6long, 2), 10); } /** * 数字转为IPv6地址 * 数字长度38位 */ public function long2ip_v6($dec) { if (function_exists('gmp_init')) { $bin = gmp_strval(gmp_init($dec, 10), 2); //10进制 -> 2进制 } elseif (function_exists('bcadd')) { $bin = ''; do { $bin = bcmod($dec, '2') . $bin; //10进制 -> 2进制,获取$dec/2的余数 $dec = bcdiv($dec, '2', 0); // dec/2的值,0表示小数点后位数 } while (bccomp($dec, '0')); } else { // trigger_error('GMP or BCMATH extension not installed!', E_USER_ERROR); return 'GMP or BCMATH extension not installed!'; } $bin = str_pad($bin, 128, '0', STR_PAD_LEFT); // 给2进制值补0 $ip = array(); for ($bit = 0; $bit <= 7; $bit++) { $bin_part = substr($bin, $bit * 16, 16); // 每16位分隔 $ip[] = dechex(bindec($bin_part)); // 2进制->10进制->16进制 } $ip = implode(':', $ip); // inet_pton:将可读的IP地址转换为其压缩的in_addr表示形式 // inet_ntop:将打包的Internet地址转换为可读的表示形式 return inet_ntop(inet_pton($ip)); }
最新回复(0)