AZDG算法java实现

这个算法不知道什么时候出来的,discuz中用它来记录用户信息,存到客户端浏览器的cookie中,每次请求时,服务端解开它,得到用户信息,下面这段代码是java的实现,从网上搜到一些原始代码,改造了一下。

性能还可以,双核2G主频,8线程,可以稳定在13万tips以上,从数据库、cache取数据要高效非常多

明文、密码越长加密越慢,相同明文、密码,每次加密结果不同,解密结果相同

不知道他的安全性怎样,discuz应该不会犯这种错误吧。如果可靠,用来解决“多服务器集群session共享问题”是个好办法,discuz就是用这种方法。


package com.huawei.core.common.util;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;   
import com.sun.org.apache.xml.internal.security.utils.Base64;   
 
public class AzDGCrypt {
    /**  
    * 加密函数  
    * @param txt     string      等待加密的原字串  
    * @param key     string      私有密匙(用于解密和加密)  
    * @return        string      经过私有密匙加密后的结果  
    */  
    public final static String encrypt(String txt, String key){         
        //使用随机数发生器产生 0~32000 的值并 MD5()
        String encryptKey = Utils.md5(int2Bytes((int)(Math.random() * 32000)));   
        int ctr = 0;   
        StringBuilder ciphertext = new StringBuilder();
        int len = txt.length();
        int ekLen = encryptKey.length();

        for(int i = 0; i < len; i++) {   
            ctr = ctr == ekLen ? 0 : ctr; //如果ctr = encryptKey 的长度,则ctr清零   
            char a1 = encryptKey.charAt(ctr);   
            char t1 = txt.charAt(i);   
            char t2 = encryptKey.charAt(ctr++);   
            char a2 = (char)(t1 ^ t2);
            ciphertext.append(a1).append(a2);
        }   
        return Base64.encode((passport_key(ciphertext.toString(), key)).getBytes());   
    }
       
    /**  
    * 解密函数  
    * @param    string      加密后的字串  
    * @param    string      私有密匙(用于解密和加密)  
    * @return   string      字串经过私有密匙解密后的结果  
    * @throws Base64DecodingException   
    */  
    public final static String decrypt(String ciphertext, String key) throws Base64DecodingException {   
        String txt = passport_key(new String(Base64.decode(ciphertext)), key);
        int len = txt.length();
        StringBuilder plaintext = new StringBuilder();
        
        for (int i = 0; i < len; i++) {   
            //txt的第i位,与 txt的第i+1位取异或   
            plaintext.append((char)(txt.charAt(i) ^ txt.charAt(++i)));   
        }   
        return plaintext.toString();   
    }
    
    /**  
    * Passport 密匙处理函数  
    * @param    string      待加密或待解密的字串  
    * @param    string      私有密匙(用于解密和加密)  
    * @return   string      处理后的密匙  
    */  
    private final static String passport_key(String txt, String key){   
        String encryptKey = Utils.md5(key);   
        int ctr = 0;
        int len = txt.length();
        int ekLen = encryptKey.length();
        StringBuilder plaintext = new StringBuilder();
        
        for(int i = 0; i < len; i++) {   
            ctr = ctr == ekLen ? 0 : ctr;   
            plaintext.append((char)(txt.charAt(i) ^ encryptKey.charAt(ctr++)));   
        }   
        return plaintext.toString();   
    }
    
    private final static byte[] int2Bytes(int x) {
        byte[] v = new byte[4];
        
        for(int i = 0; i < 4; i++) { //小端序,因为不需要还原
            v[i] = (byte)x;
            x >>= 8;
        }
        
        return v;
    }
       
    public static void main(String[] args) throws Exception {
        int threadNum = 8;
        final int N = 1000000;
        final CountDownLatch counter = new CountDownLatch(threadNum);
        ExecutorService exectors = Executors.newFixedThreadPool(threadNum);  
        final String txt = "dddaa000000000000000aeee";
        final String key = "ddd000000000000000000000";
        
        long t1 = System.currentTimeMillis();
        
        for(int j = 0; j < threadNum; j++) {
            exectors.execute(new Runnable(){
                public void run() {
                    String s;
                    System.out.println("start");
                    try {
                        for(int i = 0; i < N; i++) {
                            s = AzDGCrypt.encrypt(txt, key);
                            //System.out.println("txt:" + txt + " key:" + key + " txt after crypt:" + s);
                            s = AzDGCrypt.decrypt(s, key);
                            //System.out.println("txt:" + txt + " key:" + key + " txt after decrypt:" + s);
                        }
                    } catch(Exception e) {
                        e.printStackTrace();
                    }
                    counter.countDown();
                    System.out.println("end");
                }
            });
        }
        counter.await();
        long t2 = System.currentTimeMillis();
        System.out.println("speed=" + (1000 * (threadNum * N / (t2 - t1))));
        System.exit(0);
    }
       


 

posted @ 2013-06-07 20:02  爱生活,爱编程  阅读(503)  评论(0编辑  收藏  举报