You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何这段PHP代码误报JOAAT哈希值存在数组重复?

问题描述

我编写了如下PHP代码:

$num = 0;
$arr = array();

for ($i = 1; $i <= 10000; $i++) {
    $hashed = hash("joaat", "TEST" . $num + $i);
    if (!in_array($hashed, $arr)) {
        array_push($arr, $hashed);
    } else {
        // array_push($arr, $hashed);
        echo "Duplicate " . $hashed . "\n";
        echo "<br>";
        echo "TEST" . $num + $i;
        echo "<br>";
        break;
    }
}

echo "ARRAY---------------------------------------------------------------------------------------------------------------------------------";
echo "<br>";

print_r($arr);

代码逻辑为:循环生成"TEST1"至"TEST10000"的字符串,使用JOAAT哈希算法计算哈希值,检查该哈希值是否存在于数组$arr中。若不存在则将其加入数组,若存在则输出重复信息并终止循环。

实际运行时,程序触发了else分支,输出重复哈希值及原字符串并终止,但我查看数组后却未找到该重复哈希值。请问这是什么原因?是否我的代码存在缺陷?


问题根源:运算符优先级错误

你的代码存在明确缺陷,核心问题是PHP运算符优先级导致字符串拼接逻辑完全偏离预期:

在PHP中,算术运算符(+)的优先级高于字符串连接运算符(.),所以代码中的"TEST" . $num + $i会被PHP解析为:

("TEST" . $num) + $i

而非你预期的"TEST" . ($num + $i)。

具体执行过程:

  1. $num的值为0,"TEST" . $num会生成字符串"TEST0"。
  2. 字符串与数字执行加法时,PHP会强制将字符串转换为数字:"TEST0"无法被解析为有效数字,会被转为0。
  3. 最终"TEST0" + $i的结果是0 + $i = $i(整数类型)。
  4. 调用hash("joaat", $i)时,PHP会把整数$i转为字符串(如"1"、"2")来计算哈希。

为什么会出现“重复却找不到哈希”的矛盾?

当循环到某个$i时,hash("joaat", (string)$i)的结果恰好和之前某个$j的哈希碰撞,程序进入else分支。但你在输出原字符串时同样犯了运算符优先级错误:echo "TEST" . $num + $i输出的不是"TESTX",而是$i的数值(同样的优先级逻辑,"TEST0"转0加$i等于$i),这就导致你误以为重复的是某个"TESTX"的哈希,但实际上数组里存的是数字字符串的哈希,你看到的输出数字对应的哈希确实在数组中,只是被错误的输出误导了。


修复方案

给$num + $i加上括号,强制改变运算顺序,确保先计算数值再拼接字符串:

// 修正哈希计算的字符串拼接逻辑
$hashed = hash("joaat", "TEST" . ($num + $i));
// 同时修正输出语句的运算符优先级问题
echo "TEST" . ($num + $i);

修改后代码就能按照预期生成"TEST1"到"TEST10000"的字符串并计算哈希,不会再出现逻辑错误。

内容的提问来源于stack exchange,提问作者Jugs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 22:45:14