将 Redis 输出字符串转换为位字符串

Swa*_*aha 2 string hex redis

127.0.0.1:6379> setbit mykey 1 1
(integer) 0
127.0.0.1:6379> setbit mykey 23 1
(integer) 0
127.0.0.1:6379> setbit mykey 345 1
(integer) 0
127.0.0.1:6379> get mykey
"@\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@"
127.0.0.1:6379>
Run Code Online (Sandbox Code Playgroud)

我想解析上面的输出字符串(作为一串位,如“100000000011...”)以获取设置位的索引,我该怎么做?

Gua*_*Zuo 5

你知道它setbit只是设置了字符串的位,所以它mykey保存着一个字符串。当您使用该命令时get mykey,它仅返回字符串值。

而且它\x00也是一个字符,你可以参考这个ASCII Table

每个字符有八位,位图由字符串中每个字符的所有位组成。它的顺序是每8位的顺序是字符串中char的顺序,并且每8位中,位的顺序是从高位到低位。例如,字符串为@\x00,则字符串长度为2,位长度为16。 的ascii值为@十进制的64, 的ascii值为\x000。

所以它的位图是:

0100 0000 0000 0000 
Run Code Online (Sandbox Code Playgroud)

所以它们的偏移量从左到右是从0到15。

如果你对此有疑问,可以在redis-cli中执行以下命令进行测试:

setbit test 1 1
setbit test 15 0
get test
Run Code Online (Sandbox Code Playgroud)

这将是@\x00

这样位图和字符串的关系就很清楚了,我们可以通过字符串来得到我们想要的位图。

只需使用一个简单的 python 脚本:

s = "@\x00"
bitmap = ""
for c in s:
    x = ord(c)
    str = bin(x).split('b')[1]
    if len(str) < 8 : 
       str = '0' * (8-len(str)) + str
    bitmap += str
print bitmap
Run Code Online (Sandbox Code Playgroud)

在这个脚本中,它使用ord来获取 char 的 ascii 值,并使用 bin 将 dec 转换为 bin,并在长度小于 8 时在高位加 0

输出是:

0100000000000000
Run Code Online (Sandbox Code Playgroud)