Redis二进制反转算法分析
在 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二进制反转算法分析的更多相关文章
- Redis二进制安全
为了便于理解,举一个例子: 在很多编辑器中,都会默认/n是换行字符,也就意味着一串字符存进去,涉及/n都会做一个默认的转义处理,这在编辑语言中,C也有这个特性,例如字符串Hello,\0 World! ...
- 关于Redis 二进制内容的 可视化尝试
二进制内容的 能否可视化? 网上的资料比较少啊! -------------------------------------------------------------------------- ...
- Redis二进制安全概念
二进制安全是指,在传输数据时,保证二进制数据的信息安全,也就是不被篡改.破译等,如果被攻击,能够及时检测出来. 二进制安全包含了密码学的一些东西,比如加解密.签名等. 举个例子,你把数据1111000 ...
- ACM_Reverse Bits(反转二进制)
Reverse Bits Time Limit: 2000/1000ms (Java/Others) Problem Description: Reverse bits of a given 32 b ...
- [转]Redis实现分析
Redis实现分析 浏览次数:1018次 KITERUNNER_T 2014年10月19日 字号: 大 中 小 分享到: QQ空间 新浪微博 腾讯微博 人人网 豆瓣网 开心网 更多 1 1 环境准 ...
- Redis 5种主要数据类型和命令
redis是键值对的数据库,有5中主要数据类型: 字符串类型(string),散列类型(hash),列表类型(list),集合类型(set),有序集合类型(zset) 几个基本的命令: KEYS * ...
- 预热一下吧《实现Redis消息队列》
应用场景 为什么要用redis?二进制存储.java序列化传输.IO连接数高.连接频繁 一.序列化 这里编写了一个java序列化的工具,主要是将对象转化为byte数组,和根据byte数组反序列化成ja ...
- go中redis使用小结
最近做了个关于redis的项目,那么就整理下遇到和未遇到的问题 1.redis的简介安装 2.redis的数据结构 3.Redis基本使用 4.Redis的并发 5.Redis的落地 一.redis的 ...
- Linux+Redis实战教程_day02_3、redis数据类型_4、String命令_5、hash命令_6、java操作redis数据库技术
3. redis数据类型[重点] redis 使用的是键值对保存数据.(map) key:全部都是字符串 value:有五种数据类型 Key名:自定义,key名不要过长,否则影响使用效率 Key名不要 ...
随机推荐
- cookie与session的区别?
一.cookie机制和session机制的区别 具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案.同时我们也看到,由于才服务器端保持状态的方 ...
- linux系统编程--文件IO
系统调用 什么是系统调用: 由操作系统实现并提供给外部应用程序的编程接口.(Application Programming Interface,API).是应用程序同系统之间数据交互的桥梁. C标准函 ...
- 小米 oj 硬币比赛(思维+动态规划)
硬币比赛 序号:#47难度:困难时间限制:1000ms内存限制:10M 描述 有 n 个不同价值的硬币排成一条线.有 A 与 B 两个玩家,指定由 A 开始轮流(A 先手,然后 B,然后再 A..) ...
- 【线性代数】1-1:线性组合(Linear Combinations)
title: [线性代数]1-1:线性组合(Linear Combinations) toc: true categories: Mathematic Linear Algebra date: 201 ...
- FatMouse's Speed
J - FatMouse's Speed DP的题写得多了慢慢也有了思路,虽然也还只是很简单的DP. 因为需要输出所有选择的老鼠,所以刚开始的时候想利用状态压缩来储存所选择的老鼠,后面才发现n太大1& ...
- 13.调整数组顺序使奇数位于偶数前面 Java
思路 两次遍历,第一次把奇数加到list中,第二次把偶数加到list中,时间复杂度为O(n). 利用类似于插入排序的方法,但时间复杂度为O(n^2). 代码 import java.util.Arra ...
- Java后端开发规范
基于阿里巴巴JAVA开发规范整理 一.命名风格 [强制]类名使用 UpperCamelCase 风格,必须遵从驼峰形式,但以下情形例外:DO / BO / DTO / VO / AO 正例:Marco ...
- jwt token and shiro
openapi可以完全开放访问,也可以使用jwt token进行简单的认证,还可以使用shiro支持更细致的权限管理. handler.yml配置了security和shiro两个handler: s ...
- 【软件工程】Beta冲刺(5/5)
链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 将数据分析以可视化形式展示出来 新增数据分析展示等功能API 服务器后端部署, ...
- Android中常见的默认实现类
* Basexxx* Defaultxxx* Simplexxx* Baicxxx