A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 周兴中 中级黑马   /  2012-6-24 18:12  /  1803 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 周兴中 于 2012-6-25 01:27 编辑
  1. public static void encode(byte[] in, byte[] out, int password) {  
  2.                 int len = in.length;  
  3.          
  4.                 int seed = password ^ 0x3e1e25e6;  
  5.                 for (int i = 0; i < len; ++i) {  
  6.                         byte a = (byte) ((in[i] ^ seed) >> 3);  
  7.                     //说明①: in[i]的高5位给了a的低5位   
  8.                     byte b = (byte) (((((int) in[i]) << 18) ^ seed) >> (18 - 5));  
  9.                     //说明②: in[i]的低3位给了b的高3位   
  10.                     a &= 0x1f;  
  11.                     //0x1f=16+15=31=2^5-1=00011111;   
  12.                     b &= 0xe0;  
  13.                     //0xe0=11100000;   
  14.                     out[i] = (byte) (a | b);  
  15.                     seed = (seed * 84723701 ^ seed ^ out[i]);  
  16.                 }  
  17.             }  
  18.          
  19.             public static void decode(byte[] in, byte[] out, int password) {  
  20.                 int len = in.length;  
  21.                 int seed = password ^ 0x3e1e25e6;  
  22.                 for (int i = 0; i < len; ++i) {  
  23.                     // fill the code here  
  24.                         byte a = (byte) (in[i] & 0x1f);  
  25.                         //参照式⑤,还原输出结果,取in[i]的低5位   
  26.                                     byte b = (byte) (in[i] & 0xe0);   
  27.                         //参照式⑤,还原输出结果,取in[i]的高3位   
  28.                                     a = (byte) (((a <<3) ^ seed) & 248);   
  29.                         //参照定理三B ^ A^ A = B,参照式①byte a = (byte) ((in[i] ^ seed) >>> 3)   
  30.                         //式①中的in[i]相当于B,seed相当于A,(a<<3)相当 B ^ A 故((a <<3) ^ seed)表示in[i]高5   
  31.                         //位的这5个数字,为了将这5个数字放入高5位的位置上,还需&11111000,即&248。   
  32.                         //11111000=2^7+2^6+2^5+2^4+2^3=128+64+32+16+8=248   
  33.                                     b = (byte) ((((((int) b) << (18 - 5)) ^ seed) >> 18) & 7);  
  34.                         //类似地,逆向式②,得到的结果将放入out[i]的低3位,故&00000111,即&7。   
  35.                         //00000111=2^0+2^1+2^2=1+2+4=7   
  36.                                     out[i] = (byte) (a | b);  
  37.                                     seed = (seed * 84723701 ^ seed ^ in[i]);
  38.                 }  
  39.             }  
复制代码
这是一个sougou(搜狗)面试题,通过这个题,想知道有没有什么技巧,可以通过编码算法,可以很快的推敲出解码算法.反之亦然. (这道题看起来算法很短,但是推敲起来还是有点头大)
我想这对很多面试者或未来从事编码解码的同学是有帮助的请高人指点指点.

就是说,当你拿到一个加密算法时,如何通过分析,该用什么样的思路,还原出解决算法.

评分

参与人数 1黑马币 +10 收起 理由
黄奕豪 + 10

查看全部评分

1 个回复

正序浏览
我来回一个吧,不知道楼主问这个问题的目的是什么。
如果是编解码的话,知道编码,就一定知道解码,因为目的就的让你知道。所以你找到对应的编码算法就好了
但是如果是密码的话,密码的目的是保护你的数据,而且密码学有一个原则就是算法公开,也就是说你知道这个密码的算法,但是如果不知道密钥的话,还是不知道对应的数据是怎么样的。对一段数据编码与密码的区别类似于,比如我的原始数据是0,编码就是我这个数据加一,也就是变成1了,那么相应的解码算法是-1,密码就是告诉你,我这个加密算法是通过加法算出来的,我将原始数据加了x,x是多少就是所说的密钥,那么你就算拿到加密后的数据,你由于不知道x,那么你还是不知道它原始的数据是0还是别的。。
当然这是个简单的比喻,真正的密码学和编码远远比这个要复杂的多,统计学,矩阵,集合,图论,可以说密码学涉及到数学的方方面面,你让我们拿到一个加密算法来分析还原它的解法,实在是有些强人所难了,能真正正确回答这个问题的人估计回答的你也不可能听懂。。
说了这么多,我想说的其实是,如果只是需要编码解码的话,只需要知道某些编码的名字,当然你能了解编码的细节也可以,不了解也无所谓,比如我知道一段数据是通过base64编码的,那么我要解码就在百度里面搜,java base64 解码,一般就能知道如何做了。
编解码还有一些就是在图像啊,视频啊里面经常会有那种算法的,你最应该知道的就是那个东西到底叫什么,然后在java语言中找到它相对应的对象。
不知道这段回答能否让你满意。

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马