PHP实现ProvablyFair算法如何将字节转换为0-255范围十进制值
问题核心错误点
- PHP内置
hash_hmac函数默认返回十六进制编码的字符串,而非原始二进制哈希字节,你直接对默认返回值做unpack操作,拿到的是十六进制字符对应的ASCII码,不是哈希本身的字节值 - 不需要调用
octdec做转换,unpack('C*')格式符解原始二进制得到的结果本身就是0-255区间的十进制整数,你误用了八进制转十进制的函数
修正后的可运行代码
<?php $K = "95ac4ed338c4b1e9ce4a0e2fb7bb400fa7f3ee5e62264432acb37e27619fe2ec"; $clientSeed = 98889; $nonce = 21; $row_number = 1; $message = "{$clientSeed}:{$nonce}:{$row_number}:0"; // 第四个参数设为true,获取原始二进制哈希结果,这是核心修正点 $goHash = hash_hmac('sha256', $K, $message, true); // 直接解包原始二进制为无符号字节数组,每个元素天然就是0-255的十进制值 $byte_array = array_values(unpack('C*', $goHash)); $Get_1St_4_Bytes = array_slice($byte_array, 0, 4); $byte1 = $Get_1St_4_Bytes[0]; $byte2 = $Get_1St_4_Bytes[1]; $byte3 = $Get_1St_4_Bytes[2]; $byte4 = $Get_1St_4_Bytes[3]; // 输出验证 echo "哈希值(十六进制): " . bin2hex($goHash) . "<br><br>"; echo "前4个字节对应0-255十进制值:[$byte1] [$byte2] [$byte3] [$byte4]"; ?>
补充说明
如果不需要保留整个字节数组,也可以直接通过unpack格式符一次性提取前4个字节,写法更简洁:
// N代表无符号长整型(大端序),直接把前4个字节合并为32位整数,也可以单独拆分提取 $first4Int = unpack('N', $goHash)[1]; // 单独拆分每个字节的话也可以用位运算实现 $byte1 = ($first4Int >> 24) & 0xFF; $byte2 = ($first4Int >> 16) & 0xFF; $byte3 = ($first4Int >> 8) & 0xFF; $byte4 = $first4Int & 0xFF;
内容的提问来源于stack exchange,提问作者No_Name
相关产品推荐
相关产品推荐

