我正在处理一些对于 PHP 来说太大而无法处理的数字(二进制的 IPv6 地址),所以为了解决这个问题,我制定了一个函数来将地址转换为二进制字符串(实际上只是一个字符串1 和 0)。然而,当谈到子网计算时,我知道如何做到这一点的最简单方法是使用二进制数学。我不知道在这种情况下如何使用二进制数学,因为我在技术上处理的是字符串,而不是二进制数。有什么办法可以用二进制数的字符串表示来进行二进制数学吗?
问问题
183 次
2 回答
2
处理大二进制数时,您可以使用GMP 扩展。它接受任意长度的字符串作为参数。
于 2013-05-13T19:00:20.623 回答
0
仔细想想,答案其实很简单。我刚刚编写了自己的函数来将数组拆分为 32 个字符的段(以允许 32 位系统兼容,因为 2^32 是 32 位 PHP 实现中可以达到的最高整数),对每个段执行操作分段,然后将其拼凑起来。但是,该函数强制执行长度为 128 的二进制字符串(如果传入较短的字符串,则填充较短的字符串),这就是我所需要的。它可以很容易地修改以允许任何长度的二进制字符串。这是功能:
function ipm_binmath($a, $b, $operand){
$binregex = "/\b[01]*\b/";
if (strlen($a) > 128 || strlen($b) > 128){
throw new Exception("ipm_binmath accepts binary strings no greater than 128 characters.");
}
preg_match($binregex, $a, $amatches);
preg_match($binregex, $b, $bmatches);
if ($amatches[0] != $a){
throw new Exception("Invalid data passed to ipm_binmath - \$a is not a binary string.");
}
if ($bmatches[0] != $b){
throw new Exception("Invalid data passed to ipm_binmath - \$b is not a binary string.");
}
$aarr = str_split(str_pad($a, 128, "0", STR_PAD_LEFT), 32);
$barr = str_split(str_pad($b, 128, "0", STR_PAD_LEFT), 32);
$ret = "";
for ($i=0; $i<4; $i++){
switch (strtoupper(trim($operand))){
case "AND":
$ret .= str_pad(decbin((bindec($aarr[$i]) & bindec($barr[$i]))), 32, "0", STR_PAD_LEFT);
break;
case "OR":
$ret .= str_pad(decbin((bindec($aarr[$i]) | bindec($barr[$i]))), 32, "0", STR_PAD_LEFT);
break;
case "XOR":
$ret .= str_pad(decbin((bindec($aarr[$i]) ^ bindec($barr[$i]))), 32, "0", STR_PAD_LEFT);
break;
default:
throw new Exception("Unsupported or invalid operand passed to ipm_binmath: '" . $operand . "'");
break;
}
}
return $ret;
}
于 2013-05-13T20:09:41.940 回答