搜狗的一道关于加密解密的笔试题,很有意思!

鉴客 发布于 2011/10/03 07:24
阅读 1K+
收藏 10

这是一道搜狗的笔试题,要求在30分钟内完成。

根据下面的 encode 方法写出对应的 decode 方法。最后运行程序输出的结果就是要求的答案。

先不看答案,trying一下吧。程序如下:

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 
        } 
    } 

    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")); 
    } 
} 

----------------------------------------------------------
最后输出结果是:搜狗输入法支持各种炫酷的皮肤,彰显个性的你!!!
其中一种实现方式为:

byte a = (byte) (((in[i]&0x7) <<5) ^seed); 
byte b = (byte) ((((((int) in[i])&0xf8) << 13) ^ seed) >>> 16); 
a &= 0xe0; 
b &= 0x1f; 
out[i] = (byte) (a | b); 
seed = (seed * 3687989 ^ seed ^ out[i]);
加载中
0
笨蛋EGG
笨蛋EGG
唉···基础没打好·····看懂了,但是不知道为什么要这样逆···呵呵·····
0
xyz555
xyz555

原理: a^b^b = a

(byte) ((in[i] ^ seed) >>> 5) & 0x7;  // 取得byte的前3位,并存放于低3位

(byte) (((((int) in[i]) << 16) ^ seed) >>> (16 - 3)) & 0xF8; // 取得低5位存放于高5位

out[i] = (byte) (a | b);  // ab合并为1个比特数

seed = (seed * 3687989 ^ seed ^ in[i]);  // 修改seed,可以使得加密后的数据更无规律

在解密里的seed = (seed * 3687989 ^ seed ^ in[i]); 和加密中的seed是等价的。

0
布拉格_Only
布拉格_Only
看不懂! 貌似基础太差了
0
sincoder
sincoder
  貌似不是 C++  是 java 吗 。。
0
sincoder
sincoder

C++ 解密函数

 

void  decode(LPBYTE  pData,DWORD Len,LPBYTE  pOut,int Password)
{
	int seed  = Password ^ 0x8c357ca5;
	for (int i = 0;i<Len;i++)
	{
		byte a = pData[i] & 0x07;
		byte b = pData[i] & 0xf8;

		byte c = ((a<<5) ^ seed) & 0xE0;  //将其低5位清0。。

		byte d = ((int(int(b) << 13) ^ seed) >> 16) & 0x1F;

		pOut[i] = c | d;

		seed = (seed * 3687989 ^ seed ^ pOut[i]); 
	}
}

0
疯狂的流浪
疯狂的流浪
密码一般都涉及到了数字逻辑运算…
返回顶部
顶部