转自:http://www.cnblogs.com/this-543273659/archive/2011/08/30/2159819.html
深入理解 按位异或 运算符
参与运算的两个值,如果两个相应的bit位相同,则结果为0,否则为1.
0^0=0;
1^0=1;
0^1=1;
1^1=0;
按位异或的三个特点(下面将以具体的东西加深理解);
(1)0异或任何数=任何数;
(2)1异或任何数=任何数取反;
(3)任何数异或自己=把自己变成了0;
可以利用异或运算法则进行特定的位翻转;【利用(1),(2)】
1.比如把第2位和第3位翻转,则可以将数与00000110进行异或运算
2.实现两个值的交换,而不必使用临时变量…这个对于代码狗有意思么,但是理解异或…
a=10100001,b=00000110
a=a^b; //10100111
b=b^a; //10100001
a=a^b; //00000110
3.判断两个数是否相等
举例1: 判断两个整数a,b是否相等【见(3)】,则可通过下列语句实现:
return ((a ^ b) == 0)
举例2: Linux中最初的ipv6_addr_equal()函数的实现如下:
static inline int ipv6_addr_equal(const struct in6_addr *a1, const struct in6_addr *a2)
{
return (a1->s6_addr32[0] == a2->s6_addr32[0] &&
a1->s6_addr32[1] == a2->s6_addr32[1] &&
a1->s6_addr32[2] == a2->s6_addr32[2] &&
a1->s6_addr32[3] == a2->s6_addr32[3]);
}
可以利用按位异或实现快速比较, 最新的实现已经修改为:
static inline int ipv6_addr_equal(const struct in6_addr *a1, const struct in6_addr *a2)
{
return (((a1->s6_addr32[0] ^ a2->s6_addr32[0]) |
(a1->s6_addr32[1] ^ a2->s6_addr32[1]) |
(a1->s6_addr32[2] ^ a2->s6_addr32[2]) |
(a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0);
}
然后按位异或的范围:整数
char类型,也就是字符类型实际上就是整形,就是数字.
计算机里面所有的信息都是整数,所有的整数都可以表示成二进制的,实际上计算机只认识二进制的.
位运算就是二进制整数运算啦.
两个数按位异或意思就是从个位开始,一位一位的比.
如果两个数相应的位上一样,结果就是0,不一样就是1
所以111^101=010
那加密的过程就是逐个字符跟那个secret字符异或运算.
解密的过程就是密文再跟同一个字符异或运算
010^101=111