转自http://shijuanfeng.blogbus.com/logs/162678019.html

以下程序是一个信息编码的程序,阅读其encode部分,并补全其decode部分
最后运行程序,会打印出的一句话。这句话就是我们要求的答案。

注意!这句话是用GBK编码的!

 

  1. //#include "stdafx.h"    
  2. #include<iostream>  
  3. typedef unsigned char   uint8_t;  
  4. typedef unsigned int   uint32_t;    
  5.  
  6.  
  7. /*解题思路:须知:1. & 即保留位为1的位。2. ^可逆。即 a^b^a = b。3. << 左移几位,就在后面补几个零,高位在结果中被丢弃; 右移同样*/ 
  8.  
  9. int  encode(const  void*  raw_in,  void*  raw_out,  uint32_t  password,  size_t  len)  
  10. {     
  11.     const  uint8_t*  in  =  (const  uint8_t*)raw_in;    
  12.     uint8_t*  out  =  (uint8_t*)raw_out;      
  13.     uint32_t  seed  =  password  ^  0x99a43ceeu;   
  14.     for  (size_t  i  =  0  ;  i  <  len;  ++i)  
  15.     {        
  16.         // 将in的1-8位与seed第1-8位异或,然后右移5位,得到一个8位,1-7位为a。    
  17.         uint8_t  a  =  (  in[i]  ^  seed  )  >>  5;          
  18.         // 将in左移13位(低位的13位均为0)的1-8位与seed第1-8位异或,然后右移10位,得到一个8位,1-7位为b。        
  19.         uint8_t  b  =  (  (  ((uint32_t)in[i])  <<  13  )  ^  seed  )  >>  (13-3);       
  20.         // 与7 ,此时a变成了 0000 0xxx          
  21.         a  &=  7;         
  22.         // 与248 ,此时b变成了 xxxx x000       
  23.         b  &=  248;         
  24.         // b  <<  3 得到 xx00 0000; 与a异或,得到xx00 0xxx;与7按位与,0000 0xxx ;       
  25.         // 换言之,这句话没用,忽悠人的        
  26.   a  =  7  &  (  a  ^  (b  <<  3));       
  27.         // out 为 xxxx x xxx ;前5位由b决定,后3位由a决定        
  28.         out[i]  =  a  |  b;        
  29.         // 更新seed        
  30.         seed  =  (seed  *  144123481  ^  seed  ^  out[i]);    
  31.     }       
  32.     return 0;  
  33. }     
  34. int  decode(const  void*  raw_in,  void*  raw_out,  uint32_t  password,  size_t  len)  
  35. {      
  36.     const  uint8_t*  in  =  (const  uint8_t*)raw_in;    
  37.     uint8_t*  out  =  (uint8_t*)raw_out;     
  38.     uint32_t  seed  =  password  ^  0x99a43ceeu;     
  39.     for  (size_t  i  =  0  ;  i  <  len;  ++i)    
  40.     {         
  41.         //  请在此处补全代码//////////////////////////////////////////     
  42.         // 取出后三位,即前5位        
  43.         uint8_t  a = in[i] & 7;    
  44.         uint8_t  b = in[i] & 248;        
  45.         //  a  =  (  in[i]  ^  seed  )  >>  5; 的逆过程    
  46.         // a 左移5位,变成xxx0 0000; 异或 seed的前3位,得到的结果为xxxx xxxx; 再位与224,得到xxx0 0000      
  47.         a=((a<<5)^seed) & 224;         
  48.         // uint8_t  b  =  (  (  ((uint32_t)in[i])  <<  13  )  ^  seed  )  >>  (13-3); 的逆过程        
  49.         // b : 0000 0000 0000 0000  0000 0000 XXXX X000 左移10位,变成0000 0000 0000 00XX  XXX0 0000 0000 0000;        
  50.         // 然后 异或seed,xxxx xxxx xxxx xxXX  XXXx xxxx xxxx xxxx          
  51.         // 再 右移13位  0000 0000 0000 0xxx  xxxx xxxx xxxX XXXX         
  52.         // 位与31 得到 0000 0000 0000 0000  0000 0000 000X XXXX        
  53.         // 因此b = 000X XXXX                 
  54.         b=(((((uint32_t)b) << 10)^seed)>>13) & 31;        
  55.         out[i] = a | b;         // in 和out 反一下就好了   
  56.         seed  =  (seed  *  144123481  ^  seed  ^  in[i]);   
  57.           
  58.  
  59.     }          
  60.     return 0;}   
  61. int  main()   
  62. {      
  63.     const  uint8_t  buf1[]  =  {0x46,  0x5c,  0x22,  0x2b,  0xa2,  0x88,  0x09,  0x15,  0x4f,  0x0c,  0x62,      
  64.         0x29,  0x12,  0x03,  0xcd,  0x84,  0xe4,  0xa7,  0xc3,  0x67,  0x00,  0x20,  0xba,  0x60,  0x6e,      
  65.         0x21,  0xf6,  0xb0,  0x71,  0x4d,  0x75,  0xea,  0x1e,  0xdd,  0x4a,  0x28,  0x32,  0x6d,  0x20,      
  66.         0x5c,  0x5a,  0x91,  0xd2,  0xd9,  0xc8,  0xcb,  0x8b,  0x53,  0x30,  0xab,  0x01,  0x8d,  0xf4,      
  67.         0x35,  0x4e,  0xc5,  0x26,  0xaa,  0x95,  0x99,  };       
  68.     uint8_t  buf2[100]  =  {};        
  69.  
  70.     const  uint32_t  password  =  0x7c8448e8u;     
  71.     const  size_t  len  =  sizeof(buf1);     
  72.     decode(buf1,  buf2,  password,  len);    
  73.       
  74.     printf("%s\n",  buf2);  

输出结果:

搜狗2012校园招聘 网上测评c++题目_GBK

ASCII码用一个字节(最左边位为0)表示一个英文字符,范围0---127

汉字用GBK编码。两个字节(共16位二进制)表示,两个字节的首位都是“1”。这种汉字编码最多可以表示128*128个汉字