搜狗网申在线测试题——编码和解码的C程序的解决

首先说明本题目的原意:以下程序是GBK编码和解码程序,根据编码过程encode(),将解码过程decode()补充完整。写出输出结果,输出结果是一句话。

下面代码是原题(程序风格都没变),说实在的,这程序员代码风格实在是,一个字乱!

#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  ^  0x55157c65u; 
for  (size_t  i  =  0  ;  i  <  len;  ++i)  { 
uint8_t  a  =  (  in[i]  ^  seed  )  >>  5; 
uint8_t  b  =  (  (  ((uint32_t)in[i])  <<  15  )  ^  seed  )  >>  (15-3); 
a  &=  7; 
b  &=  248; 
a  =  7  &  (  a  ^  (b  <<  3)); 
out[i]  =  a  |  b; 
seed  =  (((seed  <<  7)  ^  seed  ^  in[i])  +  536513); 
} 
} 


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  ^  0x55157c65u; 
for  (size_t  i  =  0  ;  i  <  len;  ++i)  { 
//  请在此处补全代码 
} 
} 
int  main() 
{ 
const  uint8_t  buf1[]  =  {0xc3,  0x27,  0x60,  0x33,  0x8f,  0x88,  0xd8,  0xc1,  0x01,  0xd1,  0xd5,  0xa2,  0x9e,  0x5b,  0x57,  0xb7,  0xd0,  0x89,  0xc5,  0x2d,  0x41,  0x91,  0x0d,  0x1c,  0x84,  0x0a,  0xee,  0x32,  0x7a,  0x89,  0xd9,  0x26,  0x25,  0xf0,  0xb3,  0x2c,  0x53,  0x68,  0x8f,  0x5f,  0x23,  0x50,  0xb0,  0xb8,  0xdc,  0x60,  0x15,  0x01,  0xc4,  0xe4,  0x0d,  0x26,  0xc5,  0x7a,  0x11,  0x16,  0xfd,  }; 
uint8_t  buf2[100]  =  {}; 
const  uint32_t  password  =  0x35bcaac9u; 
const  size_t  len  =  sizeof(buf1); 
decode(buf1,  buf2,  password,  len); 
printf("%s\n",  buf2); 
} 

分析编码过程,写出解码,如同加密和解密一样,是一个逆过程。慢慢推敲便可以补上确实代码:

        uint8_t a = 7 & in[i];
        uint8_t b = 248 & in[i];
        b = 31 & ( ( ( (uint32_t)b << 12) ^seed) >> 15);
        a = 224 & ( (a << 5) ^ seed);
        out[i] = a | b; 
    
        seed = ( ( (seed << 7) ^ seed ^ out[i]) + 536513);

程序的运行环境是Linux,编译命令gcc -std=c99 -o code code.c;   这样执行结果居然是乱码!!!然后我就怀疑我的解码程序有问题,我就检查了数小时,实在认为我写的没有错误,然后我就协议几个测试用例进行完整的编码和解码,结果能够正常解码。这就奇怪了!然后,我又查网友的资料,结果查不到,我请大牛同学帮忙,请网上认识的高人。大牛和高人要么是忙,要么直接不摆我,伤心啊。

我一度认为是他们给定的要解码的源数据有问题。我不死心又上了他的在线测试系统,结果还是乱码,纠结!怎么能这样?半小时后又交了白卷。

最后,我终于下定决心,将Linux下的代码移植到Window XP下的VC 6.0上。(我的编程环境还是很全乎的)然后我把代码改成了这样:

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

#define uint8_t unsigned char
#define uint32_t unsigned int
#define size_t unsigned int


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

    uint32_t seed = password ^ 0x55157c65u;
	size_t i;
    for  (i = 0; i < len; ++i)
    {
        a = ( in[i] ^ seed) >> 5;
        b = ( ( ( (uint32_t)in[i]) << 15) ^ seed) >> (15-3);
        a &= 7;
        b &= 248;
        a = 7 & (a ^ (b << 3));
        out[i] = a | b;
        seed = ( ( (seed << 7) ^ seed ^ in[i]) + 536513);
    }
	return 0;
}

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

    uint32_t seed = password ^ 0x55157c65u;
	size_t i;
    for  (i = 0; i < len; ++i)
    {
        a = 7 & in[i];
        b = 248 & in[i];
        b = 31 & ( ( ( (uint32_t)b << 12) ^seed) >> 15);
        a = 224 & ( (a << 5) ^ seed);
        out[i] = a | b;

        seed = ( ( (seed << 7) ^ seed ^ out[i]) + 536513);
    }
	return 0;
}

int  main() 
{ 
	const uint8_t buf1[] = {0xc3, 0x27, 0x60, 0x33, 0x8f, 0x88, 0xd8, 0xc1, 0x01, 0xd1, 0xd5, 0xa2, 0x9e, 0x5b, 0x57, 0xb7, 0xd0, 0x89, 0xc5, 0x2d, 0x41, 0x91, 0x0d, 0x1c, 0x84, 0x0a, 0xee,  0x32, 0x7a, 0x89, 0xd9, 0x26, 0x25, 0xf0, 0xb3, 0x2c, 0x53, 0x68, 0x8f, 0x5f, 0x23, 0x50, 0xb0, 0xb8, 0xdc, 0x60, 0x15, 0x01, 0xc4, 0xe4, 0x0d, 0x26, 0xc5, 0x7a, 0x11, 0x16, 0xfd, }; 
	uint8_t buf2[100] = {0}; 
	const uint32_t password = 0x35bcaac9u; 
	const size_t len = sizeof(buf1); 
	decode(buf1, buf2, password, len); 
	printf("%s\n", buf2); 
	return 0;
} 

可以对比一下代码的变化,好消息是结果出来了,正是下图:


至此,问题算是源码解决了,然后我花了9分钟进行了第三次在线测试,成功了。至于Linux下为什么显示不出来?暂时还不好说,因为我自己的测试用例正确地执行了,以后再慢慢发现吧。

注:关于Linux/Unix字符<------->Window下字符转化问题,我一向是先考到UltraEdit-32下,然后再考到Window下的其他编程环境下。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值