位运算中的异或运算什么意思,异或位运算怎么算

  位运算中的异或运算什么意思,异或位运算怎么算

  位运算是非常迅速的,因为它直接对内存中的二进制数据进行操作。

  按位运算除了,按位与,按位非,按位左移,按位右移,还有按位异或。

  按位异或运算定义,

  1 ^ 1=0

  1 ^ 0=1

  0 ^ 1=1

  0 ^ 0=0

  异或,就是"看看你们到底一样不一样。不一样就为1,一样就为0。"

  按位异或运算的规律是

  定理一=

  定理二a ^ b ^ c=a ^(b ^ c)=(a ^ b)^ c;

  定理三^ ^=b,^ a^=b,^ a^

  定理四若d=a ^ b ^ c,则缺乏维生素

  证明:

  在^ ^两边同时异或^ b ^ c,得

  =

  d ^ b ^ c=a ^ b ^ b ^ c ^ c,由定理三得

  d ^ b ^ c=a ^ c ^ c,同样由定理三得

  ^ ^ c=a

  (1) 实现两个值的交换,而不必使用临时变量。

  例如交换两个整数a=10100001,b=00000110的值,可通过下列语句实现:

  a=a^b;//a=10100111

  b=b^a;//b=10100001

  a=a^b;//a=00000110

  (2) 在汇编语言中经常用于将变量置零:

  异或答,答

  (3) 使某些特定的位翻转

  例如对数10100001的第2位和第3位翻转,则可以将该数与00000110进行按位异或运算。

  10100001^00000110=10100111

  (4)使用定理三进行编码解码

  由^ A^ A=B,我们可以假设一聊天记录是b,密钥是答。现在B^A之后,成了密文了。为了解密,对密文再使用密钥A进行一次异或运算即可。也即是^ A^。

  看看今年搜狗校招在线测试的一道编码解码题目。原题(JAVA版本)如下

  【java】查看plaincopyprint?

  公共类测试{ publicstaticvodieencode(byte[]in,byte[]out,int password){ int len=in。长度;intseed=password^0x3e1e25e6;for(inti=0;我leni){bytea=(byte)((in[i]^seed)3);byteb=(byte)((((((int)in[i])18)^seed)(18-5));a=0x1fb=0xe0out[i]=(字节)(a b);seed=(seed*84723701^seed^out[i]);} } publistaticvoiddecode(byte[]in,byte[]out,int password){ int len=in。长度;intseed=password^0x3e1e25e6;for(inti=0;我lenI){//fillthecodehere } } publicstaticvoidmain(String[]args)throw exception { int password=0x FD B4 d0e 9;byte[]buf1={-5,9,-62,-122,50,122,-86,119,-101,25,-64,-97,-128,95,85,62,99,98,-94,76,12,127,121,-32,-125,-126,15,18,100,104,-32,-111,-122,110,-460 byte长度];解码(缓冲器1,缓冲器2,密码);系统。出去。println(新字符串(buf 2, GBK ));} }公共类测试{

  公共静态空编码(byte[] in,byte[] out,int password) {

  int len=英寸长度

  int seed=密码^0x 3 E1 e 25 e 6;

  for(int I=0;我leni) {

  字节a=(字节)((在[i] ^种子中)3);

  字节b=(byte)((((((int)in[I])18)^种子)(18-5));

  a=0x1f

  b=0xe0

  out[i]=(字节)(a b);

  seed=(seed * 84723701 ^ seed ^ out[I]);

  公共静态空的解码(byte[] in,byte[] out,int password) {

  int len=英寸长度

  int seed=密码^0x 3 E1 e 25 e 6;

  for(int I=0;我leni) {

  //在此填写代码

  公共静态void main(String[] args)引发异常{

  int password=0x FD B4 d0e 9;

  byte[] buf1={ -5,9,-62,-122,50,122,-86,119,-101,25,-64,

  -97, -128, 95, 85, 62, 99, 98, -94, 76, 12, 127, 121, -32,

  -125, -126, 15, 18, 100, 104, -32, -111, -122, 110, -4, 60, 57,

  21, 36, -82, };

  字节[]缓冲区2=新字节【buf 1。长度];

  解码(缓冲器1,缓冲器2,密码);

  System.out.println(新字符串(buf2,“GBK”);

  题目要求补充译函数。那么根据编码函数就可以补充译函数。解题要点是位运算中的左移,右移,按位与,按位异或,按位异或定理三。

  先来理解编码函数。

  【java】查看plaincopyprint?

  publistativoideencode(byte[]in,byte[]out,int password){ int len=in。长度;intseed=password^0x3e1e25e6;for(inti=0;我leni){bytea=(byte)((in[i]^seed)3);//说明:在[我]中的高5位给了a的低5位byteb=(byte)((((((int)in[i])18)^seed)(18-5));//说明:在[我]中的低3位给了b的高3位a=0x1f//0x1f=16 15=31=2^5-1=00011111;b=0x E0//0x E0=11100000;out[i]=(字节)(a b);seed=(seed*84723701^seed^out[i]);} } public static void encode(byte[]in,byte[] out,int password) {

  int len=英寸长度

  int seed=密码^0x 3 E1 e 25 e 6;

  for(int I=0;我leni) {

  byte a=(byte)((在[i] ^种子中)3);

  //描述:In[I]的高5位给a的低5位。

  byte b=(byte)((((((int)in[I])18)^种子)(18-5));

  //描述:in[I]的低3位给b的高3位。

  a=0x1f

  //0x1f=16 15=31=2^5-1=00011111;

  b=0xe0

  //0x E0=11100000;

  out[i]=(字节)(a b);

  seed=(seed * 84723701 ^ seed ^ out[I]);

  然后就可以写解码函数了。

  【java】查看plaincopyprint?

  publicstaticvoiddecode(byte[]in,byte[]out,int password){ int len=in . length;//out[I]in//encode is in[I]int seed=password0x 3 E1 e 25 e 6 in decode here;for(inti=0;我lenI){ bytea=(byte)(in[I]0x1f);//参考公式,还原输出结果,取in[i] byteb=(byte)(in[i]0xe0)的低5位;//参考公式,还原输出结果,取in[i] A=(byte) ((A 3) seed) 248)的高3位;//参考定理3 b a a=b,参考公式bytea=(byte)((in[i]seed)3)//在公式中,in[I]等价于b,seed等价于a,(a 3)等价于b a,所以((a3) seed)表示in[I . //11111000=2^7 2^6 2^5 2^4 2^3=128 64 32 16 8=248 b=(byte)(((((((int)b)(18-5))^seed)18)7);//同理,反推公式,得到的结果会放入out[i]的低3位,所以0000111,即7。//00000111=2^0 2^1 2^2=1 2 4=7 out[I]=(字节)(a b);seed=(seed*84723701^seed^in[i]);} }//最后输出的答案略雷,答案是“真双核引擎是世界上最快的浏览器内核!"公共静态void解码(byte[] in,byte[] out,int password) {

  int len=in.length//此处编码中的out[i]是解码中的in[i]

  int seed=密码^0x 3 E1 e 25 e 6;

  for(int I=0;我leni) {

  byte a=(byte)(in[I]0x1f);

  //参考公式,还原输出结果,取in[i]的低5位

  byte b=(byte)(in[I]0x E0);

  //参考公式,还原输出结果,取in[i]的高3位

  a=(字节)(((a 3) ^种子)248);

  //参考定理3 b a a=b,参考公式 byte a=(byte) ((in [I] seed) 3)

  //公式中,in[i]等价于B,seed等价于A,(a 3)等价于B A,所以((A3) seed)表示in[i]高5。

  //位的五位数还需要1111000,也就是248,才能把这五位数放在前五位。

  //11111000=2^7 2^6 2^5 2^4 2^3=128 64 32 16 8=248

  b=(byte)(((((((int)b)(18-5))^种子)18)7);

  //同理,反推公式,得到的结果会放入out[i]的低3位,所以0000111,即7。

  //00000111=2^0 2^1 2^2=1 2 4=7

  out[i]=(字节)(a b);

  seed=(seed * 84723701 ^ seed ^ in[I]);

  //最后输出答案略雷,答案是“真双核引擎是世界上最快的浏览器内核!"

  这个问题还有一个C版本,和JAVA版本几乎一模一样。

  【cpp】查看plaincopyprint?

  # include 标准传真。h #包含stdio。h//#包含stdlib。h #包含断言。h #包含字符串。h # defineu int 8 _ tunsigned char # defineu int 32 _ tunsigned int # definesize _ tunsigned int inten code(const void * raw _ in,void*raw_out,uint32_tpassword,size _ tlen){ const uint 8 _ t * in=(const uint 8 _ t *)raw _ in;uint 8 _ t * out=(uint 8 _ t *)raw _ out;uint32_tseed=password^0x3feb3c98u;for(size _ ti=0;我leni){uint8_ta=(in[i]^seed)4;uint 8 _ TB=((((uint 32 _ t)in[i])17)^seed)(17-4);a=15//00001111 b=240;//11110000=2^7 2^6 2^5 2^4=128 64 32 16=240 a=15(a^(b 3);out[I]=a b;seed=(seed*48475829^seed^in[i]);} return 0 } int decode(const void * raw _ in,void*raw_out,uint32_tpassword,size _ tlen){ const uint 8 _ t * in=(const uint 8 _ t *)raw _ in;uint 8 _ t * out=(uint 8 _ t *)raw _ out;uint32_tseed=password^0x3feb3c98u;for(size _ ti=0;我leni){//请在此处补全代码-开始uint 8 _ ta=in[I]uint 8 _ TB=in[I]240;a=((一个4)^seed)240;b=((((uint 32 _ t)b 13)^seed)17)out[i]=a b;seed=(seed*48475829^seed^out[i]);//请在此处补全代码-结束} return 0 int main(){ const uint 8 _ tbuf 1[]={0x1e,0x7b,0x8f,0x63,0x6f,0x69,0x26,0x23,0x64,0xe1,0x09,0x21,0x13,0x2b,0x37,0xdf,0xa4,0x7f,0x45,0xe3,0x6b,0xda,0x6a,0x00,0x93,0x4b,0xd1,0x81,0x92,0x20,0x69const uint 32 _ t password=0x e 53 e 6 EB 6u;constsize _ tlen=sizeof(buf 1);decode(buf1,buf2,password,len);printf(%s\n ,buf 2);return0}//输出答案:搜狗搜索是全球首个中文网页收录量达到100亿的搜索引擎!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: