搜狗 2012 校园招聘 网测题

本文探讨了一种使用C99标准进行信息编码的方法,包括编码和解码过程。通过实例展示了如何利用特定算法对数据进行加密和解密,特别关注GBK编码的应用。最终输出揭示了加密信息的真实含义,即“搜狗拼音输入法开创了基于搜索引擎全新的输入模式!!!”。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 以下程序是一个信息编码的程序,阅读其encode部分,并补全其decode部分
最后运行程序,会打印出的一句话。这句话就是我们要求的答案。 (本段代码遵循c99标准,gcc编译请加-std=c99)

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

题目:

#include  <stdio.h>
#include  <stdlib.h>
//#include  <stdint.h>
#include  <assert.h>
#include  <string.h>

typedef unsigned int uint32_t;
typedef unsigned char uint8_t;

 

int  encode(const  void*  raw_in,  void*  raw_out,  uint32_t  password,  size_t  len)
{
 const  uint8_t*  in  =  (const  uint8_t*)raw_in;
 uint8_t*  out  =  (uint8_t*)raw_out;

 uint32_t  seed  =  password  ^  0x12cfd592u;
 for  (size_t  i  =  0  ;  i  <  len;  ++i)  {
  uint8_t  a  =  (  in[i]  ^  seed  )  >>  2;
  uint8_t  b  =  (  (  ((uint32_t)in[i])  <<  12  )  ^  seed  )  >>  (12-6);
  a  &=  63;
  b  &=  192;
  a  =  63  &  (  a  ^  (b  <<  3));
  out[i]  =  a  |  b;
  seed  =  (seed  *  3687989  ^  seed  ^  out[i]);
 }
 return 0;
}


int  decode(const  void*  raw_in,  void*  raw_out,  uint32_t  password,  size_t  len)
{
 const  uint8_t*  in  =  (const  uint8_t*)raw_in;
 uint8_t*  out  =  (uint8_t*)raw_out;

 uint32_t  seed  =  password  ^  0x12cfd592u;
 for  (size_t  i  =  0  ;  i  <  len;  ++i)  {
  //  请在此处补全代码
  uint8_t a = in[i] & 63;
  uint8_t b = in[i] & 192;
  uint8_t c = ((a<<2) ^ seed ) &252;
  uint8_t d = (((((uint32_t) b) << 6) ^ seed) >> 12) & 3;
  out[i] = c | d;
  seed = ( seed * 3687989 ^ seed ^ in[i]);
 }
 return 0;
}
int  main()
{
 const  uint8_t  buf1[]  =  {0x5f,  0x5f,  0x1c,  0x19,  0x87,  0x01,  0x9b,  0xfc,  0x50,  0x85,  0x43,  0xa9,  0x82,  0xed,  0xde,  0x9e,  0x20,  0xa3,  0x70,  0xc9,  0x10,  0x67,  0xd9,  0x15,  0xd8,  0x97,  0x4b,  0xa2,  0xd1,  0x6d,  0x7f,  0xdb,  0x57,  0xca,  0xa1,  0x7e,  0x8f,  0x54,  0xd2,  0x4d,  0x4b,  0x4b,  0x9e,  0x82,  0x74,  0xec,  0x4f,  0x0f,  0x36,  0x66,  0xbf,  0x4d,  };
 uint8_t  buf2[100]  =  {};
 const  uint32_t  password  =  0xa97e3826u;
 const  size_t  len  =  sizeof(buf1);
 decode(buf1,  buf2,  password,  len);
 printf("%s\n",  buf2);
 system("PAUSE");
 return 0;
}

输出结果为:

搜狗拼音输入法开创了基于搜索引擎全新的输入模式!!!

解题思路:

推反的过程。

uint8_t  a  =  (  in[i]  ^  seed  )  >>  2; 

//in[i]为uint_t类型的元素,有8个bit位,与32位种子做异或操作,之后向右移两位(未知)得到的结果为??xxxxxx,保存在a中,原来in[i]与seed做异或操作后的低6位结果保存在a中
  uint8_t  b  =  (  (  ((uint32_t)in[i])  <<  12  )  ^  seed  )  >>  (12-6);

//同理先将in[i]转化为32位数,向左移动12位,与种子做异或操作,再将其右移6位后(未知),将其赋值给uint8_t变量b中得到xx??????。原来in[i]与seed做异或操作后的高2位结果保存在b中
  a  &=  63;

//做与操作,63的二进制形式为00111111;a & 63将a的高两位置零,a变为:00xxxxxx
  b  &=  192;

//与操作,192的二进制形式为11000000;b & 192 将b的低6位置零,b变为:xx000000
  a  =  63  &  (  a  ^  (b  <<  3));

//仔细算来,该操作并未改变a的值,属于误导的操作,分析如下,b<<3得到0000000 a为00xxxxxx a^(b<<3)结果为 00xxxxxx & 00111111= 00xxxxxx;
  out[i]  =  a  |  b;

//00xxxxxx | xx000000,将加密后的前2位和后两位组合起来
  seed  =  (seed  *  3687989  ^  seed  ^  out[i]);

//每次依据加密后的值改变种子的行为


 

解码部分:

uint8_t a = in[i] & 63;

//得到加密数据的后6位 保存为a
  uint8_t b = in[i] & 192;

//得到加密数据的前2位 保存为b
  uint8_t c = ((a<<2) ^ seed ) &252;

//做逆操作根据a=b ^ c,得 b=a ^ c,对加密部分uint8_t  a  =  (  in[i]  ^  seed  )  >>  2; 的逆转,由于>>2导致该部分数据形式为xxxxxx??将其未置部分数据清零即 &252 (11111100)
  uint8_t d = (((((uint32_t) b) << 6) ^ seed) >> 12) & 3;

//做逆操作根据a=b ^ c,得 b=a ^ c,对加密部分  uint8_t  b  =  (  (  ((uint32_t)in[i])  <<  12  )  ^  seed  )  >>  (12-6); ,由于<<12 并且 >>6得到??????xx将其未置部分数据清零

&3(00000011)
  out[i] = c | d;

//将两部分数据组合在一起
  seed = ( seed * 3687989 ^ seed ^ in[i]);

//种子部分的双方保持一致,原来的out[i]保存的是加密的数据,现在in[i]保存的是加密的数据,因此应该置为上述表达

 

 

(encode decode sougou)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值