在 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. fatal: refusing to merge unrelated histories(git pull)

    https://blog.csdn.net/lindexi_gd/article/details/52554159 (refusing to merge unrelated histories) ht ...

  2. 组合模式(Composite)---结构型

    1 基础知识 定义:将对象组合成树形结构以表示“部分-整体”的层次结构.特征:组合模式使得客户端对单个对象和组合对象保持一致的方式处理. 本质:统一叶子对象和组合对象. 目的:让客户端不再区分操作的是 ...

  3. Luogu P4398 [JSOI2008]Blue Mary的战役地图 矩阵哈希

    其实可以二分矩阵边长但是我太懒了$qwq$. 把每个子矩阵扔到$map$里,然后就没了 #include<cstdio> #include<map> #include<i ...

  4. Noip2016 提高组 Day2 T1 组合数问题

    题目描述 组合数表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3) 三个物品中选择两个物品可以有(1,2),(1,3),(2,3)这三种选择方法.根据组合数的定 义,我们可以给出计算 ...

  5. element-ui做表单验证 v-for遍历表单 自动生成校验规则 pc移动双适配

    整体思路: 1:利用element-ui的栅格实现小分辨率和大分辨率的适配 2:模拟一组数据,从中筛选出 绑定各个表单值的对象   以及生成验证规则对象 3:在script标签内 .data()外,自 ...

  6. HTML5 烟花系统

    需求:在一个虚拟烟花球中,在不同的部位填充不同颜色.质地的烟花火药:观看试放效果.最好能结合点物理学定律(以便展现火药粉被爆炸扩散到一定程度再爆炸的效果) 这是这学期的一个作业,感觉挺无聊的,纯粹是老 ...

  7. IO之复制文件的四种方式

    1. 使用FileStreams复制 这是最经典的方式将一个文件的内容复制到另一个文件中. 使用FileInputStream读取文件A的字节,使用FileOutputStream写入到文件B. 这是 ...

  8. typescript简单的应用

    简单来说typescript就是新增一下方法,以及增加类型判断 一.普通的类型判断 1.布尔类型(boolean) let isDone: boolean = false let createdByB ...

  9. Android屏幕横竖屏切换和生命周期管理的详细总结

    一般的我们去切换屏幕方向都是不希望Activity被重新创建,这时就需要对一些属性进行设置,或者使用代码设置.        今天想学一下Android屏幕横竖屏切换,但是网上很多知识不准确或不正确, ...

  10. 如何快速查找到HTML头尾对应标签?

    在使用Atom编辑器整理HTML代码的时候,希望快速找到HTML头尾对应的标签.  ctrl+m 试试看