PHP环境下如何将128位值拆分为两个64位值
PHP环境下如何将128位值拆分为两个64位值
嘿,我之前也折腾过PHP里64位和128位数值的拆分合并,刚好能给你唠唠靠谱的解决方法~
首先得明确你是把两个64位值合并成了16字节的二进制字符串,还是合并成了一个超大整数?这两种情况的拆分方式略有不同,我分别给你梳理:
情况一:合并后的128位是16字节的二进制字符串
你之前用unpack('J*')时,每个64位值对应8字节,那合并后的128位肯定是16字节的二进制数据对吧?这种情况最直接,直接用unpack按8字节拆分就行,注意字节序(大端/小端)要和你合并时保持一致:
- 如果合并时用的是大端字节序(高位字节在前):
// $combined是16字节的128位二进制字符串 $splitParts = unpack('Jhigh64/Jlow64', $combined); $high64Value = $splitParts['high64']; // 高64位的无符号长整数 $low64Value = $splitParts['low64']; // 低64位的无符号长整数
- 如果合并时用的是小端字节序(低位字节在前):
把格式符换成P就行,P对应无符号64位小端:
$splitParts = unpack('Phigh64/Plow64', $combined);
情况二:合并后的128位是超大整数(比如通过$combined = $a * (2**64) + $b得到)
PHP从7.0开始支持64位整数,数值超过64位会自动转为内部大整数类型(不会丢精度),但直接用位运算要注意符号问题,更稳妥的是用GMP扩展(大部分PHP环境都默认安装了):
// 先定义2^64和2^64-1的掩码 $pow64 = gmp_init('18446744073709551616', 10); // 2^64 $mask64 = gmp_init('18446744073709551615', 10); // 2^64 - 1 // $bigInteger是合并后的128位大整数 $low64 = gmp_and($bigInteger, $mask64); // 取低64位 $high64 = gmp_div_q($bigInteger, $pow64); // 右移64位,取高64位 // 如果需要转成普通PHP整数(64位环境下) $low64Int = gmp_intval($low64); $high64Int = gmp_intval($high64);
要是你的PHP环境没装GMP,也可以用字符串处理拆分,但容易出错,还是优先用GMP或者二进制字符串的方式。
对了,你之前提到的(ac)+(ad)+(bc)+(bd)公式,本质上应该是把两个数通过乘法展开合并?不管你用哪种合并方式,只要拆分时的字节序或移位逻辑和合并时对应上,就不会出错~
内容来源于stack exchange
相关产品推荐
相关产品推荐

