论坛首页 Java企业应用论坛

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

浏览 11946 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-10-02  
package test.gengu;

public  class  Test5  {
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) {
            // 高三位与8 7 6位异或运算
            byte a = (byte) ((in[i] ^ seed) >>> 5);
            // 低5位与seed的17 18 19 20 21位异或运算
            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)  {

//与seed的678为运算
int temp_seed0 = seed >>> 5;
byte in_high_3 = (byte) (((in[i] ^ temp_seed0)&0x07) << 5);
// 低5位与seed的17 18 19 20 21位异或运算
int temp_seed = seed >>> 13;
byte in_low_5 = (byte) (((in[i] ^ temp_seed)& 0xf8) >>> 3);
out[i] = (byte) (in_high_3 | in_low_5);

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


}
0 请登录后投票
   发表时间:2011-10-02  
佩服!多谢!原来是这样,呵呵。
0 请登录后投票
   发表时间:2011-10-03  
发现自己真的很菜,唉!
0 请登录后投票
   发表时间:2011-10-03  
/**
 * 解密方法
 */
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++){
		byte a = (byte)(((int)in[i]) & 0x07);
		byte b = (byte)(((int)in[i]) & 0xf8);
		a = (byte) (((a^(seed>>5))<<5) & 0xe0);
		b = (byte) ((((b<<13)^seed)>>16) & 0x1f);
		out[i] = (byte) (a | b);
		seed = (seed * 3687989 ^ seed ^ out[i]);
	}
}


  

服了、 搞了半天终于搞出来了!!!

感觉在Java字节操作上自己今天下午有所进步  
0 请登录后投票
   发表时间:2011-10-04  
看不懂,求教,能不能详细的说说逻辑运算和移位运算的规则;我推了一点也不知到对不对,望指教;
已知a=b^c则b=a^c;
已知a=b&c则b=a|c;
已知a=b|c则b=a&c;
已知a=b>>>c则b=a<<c;
0 请登录后投票
   发表时间:2011-10-04  
public  static  void  encode(byte[]  in,  byte[]  out,  int  password)
{
int  len  =  in.length;

int  seed  =  password  ^  0xb9d80b98;
for  (int  i  =  0  ;  i  <  len;  ++i)  {
byte  a  =  (byte)((in[i]^seed)>>>5);
byte  b  =  (byte)(((((int)in[i])<<10)^seed)>>>(10-3));
a  &=  0x7;
b  &=  0xf8;
out[i]  =  (byte)(a  |  b);
seed  =  (((seed  <<  7)  ^  seed  ^  out[i])  +  129491);
}
}


public  static  void  decode(byte[]  in,  byte[]  out,  int  password)
{
int  len  =  in.length;

int  seed  =  password ^0xb9d80b98;
for  (int  i  =  0  ;  i  <  len;  ++i)  {
byte a = (byte) (((in[i]&0x7) <<5) ^seed);
    byte b = (byte) ((((((int) in[i])&0xf8) << 7) ^ seed) >>> 10);
    a &= 0xe0;
    b &= 0x1f;
    out[i] = (byte) (a | b);
seed  = (((seed<<7)^seed^out[i]) + 129491);
}
}
public  static  void  main(String  []  args)  throws  Exception
{
int  password  =  0x9c7a7f1a;
byte[]  buf1  =  {-78,  6,  -73,  115,  82,  90,  -124,  43,  101,  -5,  42,  -39,  97,  -99,  -16,  -114,  0,  90,  -116,  59,  74,  -75,  -14,  29,  10,  73,  -107,  91,  27,  -80,  -62,  -79,  -83,  78,  };
byte[]  buf2  =  new  byte[buf1.length];
decode(buf1,  buf2,  password);
System.out.println(new  String(buf2,  "GBK"));
}



我也遇到了搜狗的这道加密解密题,过程明白了,代码如上,但是没得到正确答案,望大牛解答。
0 请登录后投票
   发表时间:2011-10-04  
piao16702155 写道
public  static  void  encode(byte[]  in,  byte[]  out,  int  password)
{
int  len  =  in.length;

int  seed  =  password  ^  0xb9d80b98;
for  (int  i  =  0  ;  i  <  len;  ++i)  {
byte  a  =  (byte)((in[i]^seed)>>>5);
byte  b  =  (byte)(((((int)in[i])<<10)^seed)>>>(10-3));
a  &=  0x7;
b  &=  0xf8;
out[i]  =  (byte)(a  |  b);
seed  =  (((seed  <<  7)  ^  seed  ^  out[i])  +  129491);
}
}


public  static  void  decode(byte[]  in,  byte[]  out,  int  password)
{
int  len  =  in.length;

int  seed  =  password ^0xb9d80b98;
for  (int  i  =  0  ;  i  <  len;  ++i)  {
byte a = (byte) (((in[i]&0x7) <<5) ^seed);
    byte b = (byte) ((((((int) in[i])&0xf8) << 7) ^ seed) >>> 10);
    a &= 0xe0;
    b &= 0x1f;
    out[i] = (byte) (a | b);
seed  = (((seed<<7)^seed^out[i]) + 129491);
}
}
public  static  void  main(String  []  args)  throws  Exception
{
int  password  =  0x9c7a7f1a;
byte[]  buf1  =  {-78,  6,  -73,  115,  82,  90,  -124,  43,  101,  -5,  42,  -39,  97,  -99,  -16,  -114,  0,  90,  -116,  59,  74,  -75,  -14,  29,  10,  73,  -107,  91,  27,  -80,  -62,  -79,  -83,  78,  };
byte[]  buf2  =  new  byte[buf1.length];
decode(buf1,  buf2,  password);
System.out.println(new  String(buf2,  "GBK"));
}



我也遇到了搜狗的这道加密解密题,过程明白了,代码如上,但是没得到正确答案,望大牛解答。


解密的时候seed  = (((seed<<7)^seed^in[i]) + 129491); 总之要反过来
0 请登录后投票
   发表时间:2011-10-05  
确实需要想想,关键看怎么把需要的那几位与SEED的哪几位进行^运算后放回原来的位置。
0 请登录后投票
   发表时间:2011-10-05   最后修改:2011-10-05
沙舟狼客 写道
看不懂,求教,能不能详细的说说逻辑运算和移位运算的规则;我推了一点也不知到对不对,望指教;
已知a=b^c则b=a^c;
已知a=b&c则b=a|c;
已知a=b|c则b=a&c;
已知a=b>>>c则b=a<<c;



只有第一项是可以的,这是GUI中图形剪切就是按这个来的,其它都不可以
a b c   举例
0=1&0   1=0|0
1=0|1   0=1&1
最后一种,你要考虑到移位溢出的问题,这种情况下是不能还原的

0 请登录后投票
   发表时间:2011-10-09  
hehoha_wj 写道
这是一道搜狗的笔试题,要求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]);


同事另一种实现decode的方法:
byte a = (byte)(in[i]^(seed>>>5));
a <<= 5;
a &= 0xe0;
byte b = (byte)(in[i]^(seed>>>13));
b>>>=3;
b &= 0x1f;
out[i] = (byte)(a|b);
seed = (seed * 3687989 ^ seed ^ out[i]);
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics