在 redis 源码中 dictScan 算法中用到了用到了非常经典的二进制反转算法,该算法对二进制的反转高效而实用,同时对于理解位运算也有非常大的帮助。先呈现源码:

/* Function to reverse bits. Algorithm from:
* http://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel */
static unsigned long rev(unsigned long v) {
unsigned long s = * sizeof(v); // bit size; must be power of 2, 此处为32
unsigned long mask = ~; //
while ((s >>= ) > ) { //循环5次
mask ^= (mask << s); // 取得想要局部对换的掩码
// 左移s位并保留低位,右移s位并保留高位,然后两部分或运算
// 这里是实现移位的精华所在,结合下面打印信息有助于理解
v = ((v >> s) & mask) | ((v << s) & ~mask);
}
return v;
}

源码的总体思路是:用迭代的思想将32位的二进制数先将前16位和后16位对换,然后将前16位二进制数的前8位和后8位对换,后16位类似,再讲前8位的二进制数的前4位和后4位对换。。。最终实现整个二进制的反转。当然这里的实现过程非常巧妙,这也是位运算神秘而神奇的特点,理解这个过程,对于理解计算机的原理都有很大的帮助。

但上面的描述得还是比较抽象,还不足以帮助理解上面的算法实现,下面来对算法的实现过程加一些打印,以便更好的理解算法的实现原理。

#include <iostream>

using namespace std;

// 打印二进制
void printBits(const unsigned long v) {
unsigned long mask = << ;
while ((mask) > ) {
int bit = (v & mask) ? : ;
cout << bit;
mask >>= ;
}
cout << endl;
} static unsigned long rev_test(unsigned long v) {
unsigned long s = * sizeof(v); // bit size; must be power of 2
unsigned long mask = ~;
cout << "s : ";
printBits(s);
cout << "mask : ";
printBits(mask); while ((s >>= ) > ) {
cout << endl;
cout << "s : ";
printBits(s);
cout << "mask : ";
printBits(mask);
cout << "mask<<s: ";
printBits(mask << s);
mask ^= (mask << s);
cout << "mask^= : ";
printBits(mask);
v = ((v >> s) & mask) | ((v << s) & ~mask);
cout << "v : ";
printBits(v);
} return v;
} int main() {
unsigned long v = ;
cout << "v : ";
printBits(v);
cout << endl;
v = rev_test(v);
cout << endl;
cout << "v : ";
printBits(v); cout << endl << endl << endl; system("pause");
return ;
}

运行上述程序结果如下:

Redis二进制反转算法分析的更多相关文章

  1. Redis二进制安全

    为了便于理解,举一个例子: 在很多编辑器中,都会默认/n是换行字符,也就意味着一串字符存进去,涉及/n都会做一个默认的转义处理,这在编辑语言中,C也有这个特性,例如字符串Hello,\0 World! ...

  2. 关于Redis 二进制内容的 可视化尝试

    二进制内容的 能否可视化?  网上的资料比较少啊! -------------------------------------------------------------------------- ...

  3. Redis二进制安全概念

    二进制安全是指,在传输数据时,保证二进制数据的信息安全,也就是不被篡改.破译等,如果被攻击,能够及时检测出来. 二进制安全包含了密码学的一些东西,比如加解密.签名等. 举个例子,你把数据1111000 ...

  4. ACM_Reverse Bits(反转二进制)

    Reverse Bits Time Limit: 2000/1000ms (Java/Others) Problem Description: Reverse bits of a given 32 b ...

  5. [转]Redis实现分析

    Redis实现分析 浏览次数:1018次 KITERUNNER_T 2014年10月19日 字号: 大 中 小 分享到: QQ空间 新浪微博 腾讯微博 人人网 豆瓣网 开心网 更多 1   1 环境准 ...

  6. Redis 5种主要数据类型和命令

    redis是键值对的数据库,有5中主要数据类型: 字符串类型(string),散列类型(hash),列表类型(list),集合类型(set),有序集合类型(zset) 几个基本的命令: KEYS * ...

  7. 预热一下吧《实现Redis消息队列》

    应用场景 为什么要用redis?二进制存储.java序列化传输.IO连接数高.连接频繁 一.序列化 这里编写了一个java序列化的工具,主要是将对象转化为byte数组,和根据byte数组反序列化成ja ...

  8. go中redis使用小结

    最近做了个关于redis的项目,那么就整理下遇到和未遇到的问题 1.redis的简介安装 2.redis的数据结构 3.Redis基本使用 4.Redis的并发 5.Redis的落地 一.redis的 ...

  9. Linux+Redis实战教程_day02_3、redis数据类型_4、String命令_5、hash命令_6、java操作redis数据库技术

    3. redis数据类型[重点] redis 使用的是键值对保存数据.(map) key:全部都是字符串 value:有五种数据类型 Key名:自定义,key名不要过长,否则影响使用效率 Key名不要 ...

随机推荐

  1. ubuntu系统升级PHP版本

    https://blog.csdn.net/qq_16885135/article/details/79747045    升级PHP7.2 https://www.cnblogs.com/lalal ...

  2. ZOJ - 4114 Flipping Game

    ZOJ - 4114 Flipping Game 题目大意:给出两个串s,t,n个灯泡的序列,1代表开着,0代表关着,一共操作k轮,每轮改变m个灯泡的状态,问最终能把s串变成t串的方案数. 坤神题解. ...

  3. CSP-S 模拟测试 51 题解

    考试过程: 惯例先看一遍三道题,T1 一开始反应要求割点,但是这是有向图,肯定不能求割点,康了一下数据范围,有40%是树的,还不错,决定待会在打. 看T2 字符串题,完了我字符串最弱了,肯定只能打暴力 ...

  4. 【原创】tarjan算法初步(强连通子图缩点)

    [原创]tarjan算法初步(强连通子图缩点) tarjan算法的思路不是一般的绕!!(不过既然是求强连通子图这样的回路也就可以稍微原谅了..) 但是研究tarjan之前总得知道强连通分量是什么吧.. ...

  5. linux上安装nginx详细步骤

    一.安装依赖包 yum install gcc gcc-c++ pcre-devel patch libffi-devel python-devel zlib-devel bzip2-devel op ...

  6. Little Prince

    You know — one loves the sunset, when one is so sad... 你知道的—当一个人情绪低落的时候,他会格外喜欢看日落...... If someone l ...

  7. response 下载文件火狐浏览器文件名乱码问题

    string path = Server.MapPath(Url.Content("~/") + "UploadFiles/Template/");       ...

  8. django快速实现完整登录系统,把登陆注册串在一起并增加cookie(六)

    1.使用之前创建的项目和应用  mysite3 account 2.使用之前的数据库构造 class User(models.Model): username=models.CharField(max ...

  9. 预处理、const、static与sizeof-sizeof与strlen有哪些区别

    1:它们的区别如下: (1)sizeof是操作符,strlen是函数. (2)sizeof操作符的结果类型是size_t,它在头文件中typedef为unsignedint类型,该类型保证能容纳实现所 ...

  10. react-hook的简单的动画插件react-simple-animate(其实是react插件,但是这里只介绍react-hook的简单用法)

    1.useAnimate(普通anima动画的形式) (1)js const animate = useAnimate({ complete: { display: 'none' }, //动画完成的 ...