2011年搜狗在线测评笔试题
根据encode方法写出对应的decode方法。最后运行程序输出的结果就是要求的答案
在iteye上早有人讨论过这题了,写下来给自己备忘下。
解题思路是按照encode的顺序去decode
如对byte a进行了3次加密操作
1.^seed
2.>>>5
3.&0x7
对byte b进行了4次加密
1.<<16
2.^seed
3.>>>14
4.&0xf8
所以在解密时候,对a也要进行3次解密,对b进行4次解密,同时要保证顺序正确
完成对byte a,b的初步解密后,因为0x7的二进制形式为 0000 0111,0xf8为1111 1000,
同样应用相反的方式去解密,此时应该用 1110 0000 和a进行&运算,用 0001 1111与b进行&运算。
最后,生成seed的时候也应该用out数组相应值参与生成seed,最后就得到decode方法相应部分的代码了。
public class Test { public static void encode(byte[] in, byte[] out, int password) { int len = in.length; int seed = password ^ 0x8c357ca5; for (int i = 0; i < len; ++i) { byte a = (byte) ((in[i] ^ seed) >>> 5); byte b = (byte) (((((int) in[i]) << 16) ^ seed) >>> (16 - 3)); a &= 0x7; b &= 0xf8; out[i] = (byte) (a | b); seed = (seed * 3687989 ^ seed ^ in[i]); } } public static void decode(byte[] in, byte[] out, int password) { int len = in.length; int seed = password ^ 0x8c357ca5; for (int i = 0; i < len; ++i) { // fill the code here byte a=(byte)((in[i]<<5)^seed); byte b=(byte)(((in[i]<<13)^seed)>>>16); a &=0xe0; b &=0x1f; out[i]=(byte)(a|b); seed =(seed * 3687989 ^ seed ^ out[i]); } } public static void main(String[] args) throws Exception { int password = 0xe87dd9d3; byte[] buf1 = { 29, -16, 96, 43, -85, 25, -96, 83, 13, 66, -109, 49, -111, 0, 60, -101, 99, -86, -38, 86, -35, 48, 23, 83, -102, 25, 73, -116, -101, -88, -5, 14, -14, -112, 87, -87, 2, 108, -58, 40, 56, 12, 108, 77, 83, 38, 20, -114, }; byte[] buf2 = new byte[buf1.length]; decode(buf1, buf2, password); System.out.println(new String(buf2, "GBK")); }}