在 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. jquery实现ajax提交表单数据或json数据

  2. 解决xftp远程连接后出现中文乱码

  3. 数据结构实验之链表八:Farey序列(SDUT 3331)

    #include <bits/stdc++.h> using namespace std; typedef struct node { int data2; int data1;//mu ...

  4. Codeforces 1205C Palindromic Paths (交互题、DP)

    题目链接 http://codeforces.com/contest/1205/problem/C 题解 菜鸡永远做着变巨的梦 然而依然连div1BC题都不会做 要是那天去打cf怕是又要1题滚粗了.. ...

  5. 微信小程序底层原理与运行机制类文章学习

    参考文档 小程序底层实现原理及一些思考 为了安全和管控, 双线程执行 Web Worker执行用户的代码; UI线程执行大部分的功能. 微信小程序架构原理 只通过mvvm模板语法动态改变页面, 不支持 ...

  6. OC和Swift进行互相调用

    swift调用oc的方法: 1.桥接文件,一般是swift工程,在创建一个oc文件时,系统自动添加(不用改名,直接默认即可) 2.将需要引用的oc文件 .h头文件 添加到桥接类中. 如下: 然后在sw ...

  7. python小技巧之把list组合成chain

    a=[] for i in range(10): a.append(i) for i,j in zip(a[:-1],a[1:]): print('%s=>%s'%(i,j)) 输出结果: 0= ...

  8. mybatis用Map<Long,List<String>>作为参数

    mapper.xml文件里的<insert id="insertByMap" parameterType="java.util.Map"> inse ...

  9. CentOS 7服务器下Nginx安装配置

    一.安装编译工具及库文件 $ yum -y install make zlib zlib-devel gcc gcc-c++ libtool openssl openssl-devel pcre pc ...

  10. koa 允许跨域

    1.安装模块 npm install koa2-cors --save 2.引用 const cors = require('koa2-cors'); ... // 允许跨域访问 app.use(co ...