某公司校园招聘在线测试题
题目:
以下程序是一个信息编码的程序,阅读其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格式这个问题,纠结了我很长时间,悲嘞个剧。