如何确定 Redis 位域中的所有设置位?

How to determine all of the set bits in a Redis bitfield?

我需要能够识别 Redis 位域中每个设置位(值=1)的索引。我发现 this 建议使用 bitpos 函数,但存在问题。据我所知,它采用字节级特异性的范围开始,因此如果给定字节中有多个设置位,我只能看到该字节中的第一个设置位。或者我可以获取整个值,但是当我这样做时我得到了错误的答案(我的代码在 PHP)。

    $temp = $redis_conn->getRange('mykey', 0, -1);
    $output = "";
    for($i=0;$i < strlen($temp); $i++) {
        $up = unpack('H*', $temp[$i]);
        $bc = base_convert($up[1], 16, 2);
        if($bc == '0') {
            $bc = '00000000';
        }
        $output .= $bc;
    }
    
    for($i = 0; $i < strlen($output); $i++) {
        if($output[$i] == '1') {
            echo ($i+1).PHP_EOL;
        }
    }

我认为这段代码应该可以工作,但答案非常不正确。我检查了一个字符串,因为当所有 8 位数字都应该为 0 时,base_convert 只给了我一位数字,使索引偏离了方向。通过查看,我可以看到还有其他地方 base_convert 的结果不是 8 位数字,这可以解释预期结果和实际结果之间的很多不匹配,但不是全部。有谁知道让这些方法中的任何一种起作用的好方法? bitpos 命令或在下拉整个位域后转换二进制文件?

编辑:举个例子,我告诉它在索引 12921、72312 和 74616 处设置位。我有 12921 按预期出现,但我看到的最高索引是 73623。

听起来您总是期望它从 base_convert() 中生成 8 个字符,但它只会提供足够的数字来表示数字。

您可以使用前导 0 填充数字以确保它始终为 8 个字符,使用 str_pad()STR_PAD_LEFT 向左填充字符串...

$output .= str_pad($bc, 8, "0", STR_PAD_LEFT);