zoukankan      html  css  js  c++  java
  • 某公司校园招聘在线测试题

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

    #include  <stdio.h> 
    #include  <stdlib.h> 
    #include  <stdint.h> 
    #include  <assert.h> 
    #include  <string.h> 
    
    
    
    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  ^  0x283265afu; 
    for  (size_t  i  =  0  ;  i  <  len;  ++i)  { 
    	uint8_t  a  =  (  in[i]  ^  seed  )  >>  3; 
    	uint8_t  b  =  (  (  ((uint32_t)in[i])  <<  20  )  ^  seed  )  >>  (20-5); 
    	a  &=  31; 
    	b  &=  224; 
    	a  =  31  &  (  a  ^  (b  <<  3)); 
    	out[i]  =  a  |  b; 
    	seed  =  (seed  *  129491  ^  seed  ^  in[i]); 
    } 
    } 
    
    
    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  ^  0x283265afu; 
    	for  (size_t  i  =  0  ;  i  <  len;  ++i)  { 
          //以下为要求编写的decode代码
    		uint8_t a = (in[i]&31);
    		uint8_t b = (in[i]&224);
    		uint8_t c =(b^(seed>>15))>>5;
    		c &= 7;
    		uint8_t d = ((a<<3)^seed);
    		d-=(d&7);
    		out[i] = c+d;
    		seed  =  (seed  *  129491  ^  seed  ^  out[i]); 
    	} 
    }
    
    
     
    int  main() 
    { 
    	const  uint8_t  buf1[]  =  {0x77,  0xc8,  0x43,  0x35,  0x56,  0xc2,  0x51,  0x43,  0x63,  0xff,  0xb1,  0x26,  0x00,  0xc4,  0x86,  0xf9,  0xe6,  0x4c,  0xe9,  0x48,  0x83,  0xa9,  0x27,  0x6a,  0xa5,  0xb2,  0x27,  0x2b,  0x98,  0x5f,  0xc0,  0x3f,  0xe0,  0xdf,  }; 
    	uint8_t  buf2[100]  =  {}; 
    	const  uint32_t  password  =  0xfbf2eeabu; 
    	const  size_t  len  =  sizeof(buf1); 
    	decode(buf1,buf2,password,len);
       printf("%s\d",buf1);
    	
    } 
    

      

      有点悲剧的。点开题目,发现答题时间是30分钟,那时候我没准备c++编译工具,后来又答了一次,发现vc6.0无法编译。好吧,我换了linux,发现用g++可以通过,大喜,但是输出的格式却不是要求的GBK,调了很久,也没输出成GBK。 最后一次,果断在linux上把输出结果输出到文件,然后再邮件到windows,再用windows打开,发现终于出现预期结果了,但是结果是一则广告。。。 

      最后写以下思路:

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

      这个仔细分析下,发现可以逆解析出原数据的一部分,后3bit丢失。

    uint8_t  b  =  (  (  ((uint32_t)in[i])  <<  20  )  ^  seed  )  >>  (20-5); 
    

      这个呢,分析可以发现后5bit是没有丢失的,可以decode出来,和前面的一款 ,可以拼接出原来的内容,接下来,只要知道a和b的值就ok了。

    a  &=  31; 
    b  &=  224; 
    a  =  31  &  (  a  ^  (b  <<  3)); 
    out[i]  =  a  |  b; 
    

      这几句话,仔细分析一下,可以发现 out = a+b;(a和b分别保留了后面几位),但是通过out用&=可以很容易反解出a和b。最后按上面的思路,逆过来就ok了。

    uint8_t a = (in[i]&31);
    uint8_t b = (in[i]&224);
    uint8_t c =(b^(seed>>15))>>5;
    c &= 7;
    uint8_t d = ((a<<3)^seed);
    d-=(d&7);
    out[i] = c+d;
    seed  =  (seed  *  129491  ^  seed  ^  out[i]); 
    

      题目,就是各种移位,但是GBK格式这个问题,纠结了我很长时间,悲嘞个剧。

  • 相关阅读:
    Mysql数据库改名
    查看数据库大小或者表大小
    Bootstarp 水平垂直居中
    Java Collection.sort 排序升序, 降序问题
    Mysql 函数, 存储过程, 任务调度
    Mysql 日期类型 date、datetime、timestamp.
    Mysql 获取当天,昨天,本周,本月,上周,上月的起始时间
    Mysql 事件event_scheduler是OFF
    Java 文件读取
    Spring cron 定时调度配置
  • 原文地址:https://www.cnblogs.com/coser/p/2171326.html
Copyright © 2011-2022 走看看