AES LINUX加密结果不一致

来源:互联网 发布:网络布线施工室分 编辑:程序博客网 时间:2024/05/16 19:23


AES对称加解密, 相同key加密结果不一致,因为Linux的强随机数而导致,需要在 jvm 加如下启动参数 


 -Djava.security.egd=file:/dev/./urandom 


如下测试类,在Linux  javac Test.java 编译 ,运行 Java Test 每次加密结果不一致。

运行 java -Djava.security.egd=file:/dev/./urandom  Test 则一致


import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import java.security.Key;import java.security.SecureRandom;import java.util.HashMap;import java.util.Map;import javax.crypto.Cipher;import javax.crypto.CipherInputStream;import javax.crypto.CipherOutputStream;import javax.crypto.KeyGenerator;import javax.crypto.spec.IvParameterSpec;//import org.apache.commons.lang3.StringUtils;public class Test {    public static void main(String[] args) throws UnsupportedEncodingException, RuntimeException {        // TODO Auto-generated method stub        String xx = "62222222222222222222";        System.out.println("xx:["+ xx +"]");                String en1 = AESUtil.encrypt(xx);        System.out.println("en1:["+ en1 +"]");                String en2 = AESUtil.encrypt(xx);        System.out.println("en2:["+ en2 +"]");                String en3 = AESUtil.encrypt(xx);        System.out.println("en3:["+ en3 +"]");                        System.out.println(">>>");        String de1 = AESUtil.decrypt("CmrCvf3jdzPihcN75poIK+dereT2XxsbUe0LWvd7p3Q*");        System.out.println("de1:["+ de1 +"]");        /*        String de2 = AESUtil.decrypt(en2);        System.out.println("de2:["+ de2 +"]");                String de3 = AESUtil.decrypt(en3);        System.out.println("de2:["+ de3 +"]");*/                    }    static class AESUtil extends AESEncrypter {        public AESUtil(String aesKey) throws RuntimeException {            super(aesKey);        }        // 因为美国对软件出口的控制,默认只支持128位;要使用256则需另下bcprov-jdk的jar包替换jre\lib\security下的jar        private static final int KEY_SIZE = 128;        private static final String aesKey = "8979d58a2a51e140a2088fb505218ce1";        /**         * @title encrypt         * @description 加密         * @author yy         * @date 2017年5月2日 上午11:17:35         * @param text         * @return         * @throws RuntimeException         * @return String         */        public static String encrypt(String text) throws RuntimeException {            if (StringUtils.isBlank(text))                return null;            return getInstance(aesKey).encode(text.getBytes());        }        /**         * @title decrypt         * @description 解密         * @author yy         * @date 2017年5月2日 上午11:17:38         * @param encryptText         * @return         * @throws RuntimeException         * @return String         */        public static String decrypt(String encryptText) throws RuntimeException {            if (StringUtils.isBlank(encryptText))                return null;            return new String(getInstance(aesKey).decode(encryptText));        }        @Override        public Key generateKey() throws Exception {            KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);            SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");            sr.setSeed(aesKey.getBytes());            kgen.init(KEY_SIZE,sr );            return kgen.generateKey();        }        public static void main(String[] args) {            System.out.println();        }    }    static class StringUtils {        public static boolean isBlank(final CharSequence cs) {            int strLen;            if (cs == null || (strLen = cs.length()) == 0) {                return true;            }            for (int i = 0; i < strLen; i++) {                if (Character.isWhitespace(cs.charAt(i)) == false) {                    return false;                }            }            return true;        }        public static String getLMTString(Object src, int limit, String supplement) {            return getLMTString(src, limit, true, true, supplement);        }        public static String getLMTString(Object src, int limit, boolean frontBegin, boolean isBack,                String supplement) {            if (src == null)                return null;            String target = src.toString();            int diffValue = target.length() - limit;            if (diffValue == 0)                return target;            else if (diffValue > 0)                return frontBegin ? target.substring(0, limit) : target.substring(diffValue, target.length());            supplement = supplement == null ? "" : supplement;            if (supplement.equals(""))                return target;            if (isBack) {                do {                    target += supplement;                } while (target.length() < limit);            } else {                do {                    target = supplement + target;                } while (target.length() < limit);            }            return target.length() == limit ? target : target.substring(0, limit);        }    }    public enum Charset {        /**         * ASCII(American Standard Code for Information         * Interchange,美国信息互换标准代码)<br/>         * 是基于罗马字母表的一套电脑编码系统,它主要用于显示现代英语和其他西欧语言<br/>         * 它是现今最通用的单字节编码系统,并等同于国际标准ISO 646         */        ASCII("ascii"),        /**         * 通常叫做Latin-1,和ASCII编码相似<br/>         * 属于单字节编码,最多能表示的字符范围是0-255,应用于英文系列         */        ISO8859_1("iso8859-1"),        /**         * GB2312又称为GB2312-80字符集,全称为<信息交换用汉字编码字符集·基本集>,由原中国国家标准总局发布,1981年5月1日实施,         * 是中国国家标准的简体中文字符集。它所收录的汉字已经覆盖99.75%的使用频率,基本满足了汉字的计算机处理需要。在中国大陆和新加坡获广泛使用         * <br/>         * GB2312收录简化汉字及一般符号、序号、数字、拉丁字母、日文假名、希腊字母、俄文字母、汉语拼音符号、汉语注音字母,共 7445         * 个图形字符。其中包括6763个汉字,其中一级汉字3755个,二级汉字3008个;包括拉丁字母、希腊字母、日文平假名及片假名字母、         * 俄语西里尔字母在内的682个全角字符。         */        GB2312("gb2312"),        /**         * GBK字符集是GB2312的扩展(K)<br/>         * GBK1.0收录了21886个符号,它分为汉字区和图形符号区,汉字区包括21003个字符。GBK字符集主要扩展了繁体中文字的支持         */        GBK("gbk"),        /**         * GB18030的全称是GB18030-2000<信息交换用汉字编码字符集基本集的扩充>,是我国政府于2000年3月17日发布的新的汉字编码国家标准         * ,2001年8月31日后在中国市场上发布的软件必须符合本标准<br/>         * GB 18030字符集标准的出台经过广泛参与和论证,来自国内外知名信息技术行业的公司,信息产业部和原国家质量技术监督局联合实施<br/>         * GB         * 18030字符集标准解决汉字、日文假名、朝鲜语和中国少数民族文字组成的大字符集计算机编码问题。该标准的字符总编码空间超过150万个编码位,         * 收录了27484个汉字,覆盖中文、日文、朝鲜语和中国少数民族文字。         * 满足中国大陆、香港、台湾、日本和韩国等东亚地区信息交换多文种、大字量、多用途、统一编码格式的要求         * 并且与UNICODE3.0版本兼容,填补UNICODE扩展字符字汇“统一汉字扩展A”的内容。并且与以前的国家字符编码标准(GB2312,         * GB13000.1)兼容         */        GB18030("gb18030"),        /**         * BIG5又称大五码或五大码<br/>         * 1984年由台湾财团法人信息工业策进会和五间软件公司宏碁 (Acer)、神通 (MiTAC)、佳佳、零壹 (Zero         * One)、大众(FIC)创立,故称大五码<br/>         * Big5码的产生,是因为当时台湾不同厂商各自推出不同的编码,如倚天码、IBM         * PS55、王安码等,彼此不能兼容;另一方面,台湾政府当时尚未推出官方的汉字编码,而中国大陆的GB2312编码亦未有收录繁体中文字<br/>         * Big5字符集共收录13,053个中文字,该字符集在中国台湾使用         */        BIG5("big5"),        /**         * 这是最统一的编码,可以用来表示所有语言的字符,而且是定长双字节(也有四字节的)编码,包括英文字母在内。所以可以说它是不兼容iso8859-1编码的         * ,也不兼容任何编码<br/>         * 不过,相对于iso8859-1编码来说,UNICODE编码只是在前面增加了一个0字节,比如字母a为"00 61"<br/>         * 需要说明的是,定长编码便于计算机处理(注意GB2312/GBK不是定长编码),而UNICODE又可以用来表示所有字符,         * 所以在很多软件内部是使用UNICODE编码来处理的,比如java         */        UNICODE("unicode"),        /**         * UTF-8是UNICODE的其中一个使用方式<br/>         * UTF-8便于不同的计算机之间使用网络传输不同语言和编码的文字,使得双字节的UNICODE能够在现存的处理单字节的系统上正确传输<br/>         * UTF-8使用可变长度字节来储存UNICODE字符,例如ASCII字母继续使用1字节储存,重音文字、希腊字母或西里尔字母等使用2字节来储存,         * 而常用的汉字就要使用3字节。辅助平面字符则使用4字节         */        UTF8("utf-8"),        /** UTF-16 使用一个或两个未分配的 16 位代码单元的序列对 UNICODE 代码点进行编码 */        UTF16("utf-16"),        /** UTF-32 即将每一个 UNICODE 代码点表示为相同值的 32 位整数 */        UTF32("utf-32");        public final String VALUE;        private Charset(String VALUE) {            this.VALUE = VALUE;        }    }    /**     * AES对称加解密     *      * @author fuli     * @version 1.0     * @date 2016-12-09 18:03     * @description 加密数据默认转换为Base64编码     */    static class AESEncrypter {        // 因为美国对软件出口的控制,默认只支持128位;要使用256则需另下bcprov-jdk的jar包替换jre\lib\security下的jar        private static final int KEY_SIZE = 128;        protected static final String KEY_ALGORITHM = "AES";        private static Map<String, AESEncrypter> encryptMap = new HashMap<String, AESEncrypter>();        private int keySize = KEY_SIZE;        private String workPattern = "ECB";        private String paddingPattern = "PKCS5Padding";        private Cipher enCipher = null;        private Cipher deCipher = null;        private B64Encrypter b64Encrypter = null;        protected String aesKey;        public AESEncrypter(String aesKey) throws RuntimeException {            init(aesKey, B64Encrypter.DEFAULT_ALPHABET, workPattern, paddingPattern, aesKey);        }        public AESEncrypter(String aesKey, boolean useHex) throws RuntimeException {            init(aesKey, useHex ? null : B64Encrypter.DEFAULT_ALPHABET, workPattern, paddingPattern, aesKey);        }        public AESEncrypter(String aesKey, String b64Key) throws RuntimeException {            init(aesKey, b64Key, workPattern, paddingPattern, aesKey);        }        public AESEncrypter(String aesKey, String workPattern, String paddingPattern) throws RuntimeException {            init(aesKey, null, workPattern, paddingPattern, aesKey);        }        public AESEncrypter(String aesKey, String b64Key, String workPattern, String paddingPattern, String ivParameter)                throws RuntimeException {            init(aesKey, b64Key, workPattern, paddingPattern, ivParameter);        }        private void init(String aesKey, String b64Key, String workPattern, String paddingPattern, String ivParameter) {            this.aesKey = aesKey;            try {                Key key = generateKey();                StringBuilder pattern = new StringBuilder(KEY_ALGORITHM);                pattern.append("/").append(workPattern);                pattern.append("/").append(paddingPattern);                enCipher = Cipher.getInstance(pattern.toString());                deCipher = Cipher.getInstance(pattern.toString());                // 使用CBC模式,需要一个向量iv,可增加加密算法的强度                if (workPattern.equals("CBC")) {                    ivParameter = StringUtils.getLMTString(ivParameter, 16, "x");                    IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes("UTF-8"));                    enCipher.init(Cipher.ENCRYPT_MODE, key, iv);                    deCipher.init(Cipher.DECRYPT_MODE, key, iv);                } else {                    enCipher.init(Cipher.ENCRYPT_MODE, key);                    deCipher.init(Cipher.DECRYPT_MODE, key);                }                if (!StringUtils.isBlank(b64Key))                    b64Encrypter = B64Encrypter.getInstance(b64Key);            } catch (Exception e) {                throw new RuntimeException("Error initializing AESEncrypter class. Cause: " + e);            }        }        // 覆盖此方法以改变Key的生成方式        public Key generateKey() throws Exception {            if (keySize != 128 && keySize != 192 && keySize != 256) {                throw new RuntimeException(                        "Error initializing AESEncrypter class. Cause: Unsupported keySize " + keySize);            }            KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);            kgen.init(keySize, new SecureRandom(aesKey.getBytes()));            return kgen.generateKey();            // OR SecretKeySpec key = new SecretKeySpec(aesKey.getBytes(),            // KEY_ALGORITHM);        }        public String encode(byte[] data) throws RuntimeException {            try {                byte[] b = enCipher.doFinal(data);                return b64Encrypter == null ? Hex.bytes2Hex(b) : b64Encrypter.encode(b);            } catch (Exception e) {                throw new RuntimeException("AESEncrypter encode error. Cause: " + e);            }        }        public byte[] decode(String encryptText) throws RuntimeException {            try {                            return deCipher                        .doFinal(b64Encrypter == null ? Hex.hexToBytes(encryptText) : b64Encrypter.decode(encryptText));                            } catch (Exception e) {                throw new RuntimeException("AESEncrypter decode error. Cause: " + e);            }        }        public void encodeFile(String file, String destFile) throws RuntimeException {            InputStream is = null;            OutputStream out = null;            CipherInputStream cis = null;            try {                is = new FileInputStream(file);                out = new FileOutputStream(destFile);                cis = new CipherInputStream(is, enCipher);                byte[] buffer = new byte[1024];                int r;                while ((r = cis.read(buffer)) > 0) {                    out.write(buffer, 0, r);                }            } catch (Exception e) {                throw new RuntimeException("AESEncrypt encodeFile error. Cause: " + e);            } finally {                StreamUtils.close(out, is, cis);            }        }        //        // public void encodeFileAsyn(String file, String destFile) throws        // RuntimeException, FileNotFoundException {        // InputStream is = new FileInputStream(file);        // CipherInputStream cis = new CipherInputStream(is, enCipher);        // OutputStream out = new FileOutputStream(destFile);        // Observable<byte[]> writer = Observable.create((subscriber) -> {        // byte[] buffer = new byte[1024];        // int r;        // try {        // while ((r = cis.read(buffer)) > 0) {        // subscriber.onNext(Arrays.copyOfRange(buffer, 0, r));        // }        // } catch (IOException ioe) {        // throw new RuntimeException("AESEncrypt encodeFileAsyn error. Cause: "        // + ioe);        // }        // subscriber.onComplete();        // });        // writer.subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).subscribe((data)        // -> {        // try {        // out.write(data);        // } catch (IOException ioe) {        // throw new RuntimeException("AESEncrypt encodeFileAsyn error. Cause: "        // + ioe);        // }        // }, (e) -> {        // StreamUtils.close(out, is, cis);        // throw new RuntimeException("AESEncrypt encodeFileAsyn error. Cause: "        // + e);        // }, () -> {        // StreamUtils.close(out, is, cis);        // });        // }        public void decodeFile(String file, String destFile) throws RuntimeException {            InputStream is = null;            OutputStream out = null;            CipherOutputStream cos = null;            try {                is = new FileInputStream(file);                out = new FileOutputStream(destFile);                cos = new CipherOutputStream(out, deCipher);                byte[] buffer = new byte[1024];                int r;                while ((r = is.read(buffer)) >= 0) {                    cos.write(buffer, 0, r);                }            } catch (Exception e) {                throw new RuntimeException("AESEncrypt decodeFile error. Cause: " + e);            } finally {                StreamUtils.close(is, out, cos);            }        }        //        // public void decodeFileAsyn(String file, String destFile) throws        // RuntimeException, FileNotFoundException {        // InputStream is = new FileInputStream(file);        // OutputStream out = new FileOutputStream(destFile);        // CipherOutputStream cos = new CipherOutputStream(out, deCipher);        // Observable<byte[]> writer = Observable.create((subscriber) -> {        // byte[] buffer = new byte[1024];        // int r;        // try {        // while ((r = is.read(buffer)) > 0) {        // subscriber.onNext(Arrays.copyOfRange(buffer, 0, r));        // }        // } catch (IOException ioe) {        // throw new RuntimeException("AESEncrypt decodeFileAsyn error. Cause: "        // + ioe);        // }        // subscriber.onComplete();        // });        // writer.subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).subscribe((data)        // -> {        // try {        // out.write(data);        // } catch (IOException ioe) {        // throw new RuntimeException("AESEncrypt decodeFileAsyn error. Cause: "        // + ioe);        // }        // }, (e) -> {        // StreamUtils.close(is, out, cos);        // throw new RuntimeException("AESEncrypt decodeFileAsyn error. Cause: "        // + e);        // }, () -> {        // StreamUtils.close(is, out, cos);        // });        // }        /********************* static method ************************/        public static AESEncrypter getInstance(String aesKey) {            return getInstance(aesKey, B64Encrypter.DEFAULT_ALPHABET);        }        public static AESEncrypter getInstance(String aesKey, boolean useHex) {            if (StringUtils.isBlank(aesKey)) {                return null;            }            String key = aesKey;            AESEncrypter aesEncrypt = encryptMap.get(key);            if (aesEncrypt == null) {                aesEncrypt = new AESEncrypter(aesKey, useHex);                encryptMap.put(key, aesEncrypt);            }            return aesEncrypt;        }        public static AESEncrypter getInstance(String aesKey, String b64Key) {            if (StringUtils.isBlank(aesKey) || !B64Encrypter.checkAlphabet(b64Key)) {                return null;            }            String key = aesKey + b64Key;            System.out.println("key:"+key);            AESEncrypter aesEncrypt = encryptMap.get(key);            if (aesEncrypt == null) {                aesEncrypt = new AESEncrypter(aesKey, b64Key);                encryptMap.put(key, aesEncrypt);            }            return aesEncrypt;        }        public static AESEncrypter newInstance(String aesKey) {            return newInstance(aesKey, B64Encrypter.DEFAULT_ALPHABET);        }        public static AESEncrypter newInstance(String aesKey, boolean useHex) {            if (StringUtils.isBlank(aesKey)) {                return null;            }            return new AESEncrypter(aesKey, useHex);        }        public static AESEncrypter newInstance(String aesKey, String b64Key) {            if (StringUtils.isBlank(aesKey) || !B64Encrypter.checkAlphabet(b64Key)) {                return null;            }            return new AESEncrypter(aesKey, b64Key);        }        public static String encrypt(String aesKey, byte[] data) throws RuntimeException {            if (StringUtils.isBlank(aesKey) || data == null)                return null;            return getInstance(aesKey).encode(data);        }        public static String encrypt(String aesKey, String b64Key, byte[] data) throws RuntimeException {            if (StringUtils.isBlank(aesKey) || !B64Encrypter.checkAlphabet(b64Key) || data == null)                return null;            return getInstance(aesKey, b64Key).encode(data);        }        public static byte[] decrypt(String aesKey, String encryptText) throws RuntimeException {            if (StringUtils.isBlank(aesKey) || StringUtils.isBlank(encryptText))                return null;            return getInstance(aesKey).decode(encryptText);        }        public static byte[] decrypt(String aesKey, String b64Key, String encryptText) throws RuntimeException {            if (StringUtils.isBlank(aesKey) || StringUtils.isBlank(encryptText) || !B64Encrypter.checkAlphabet(b64Key))                return null;            return getInstance(aesKey, b64Key).decode(encryptText);        }        /*************** File encode **************/        public static void encryptFile(String aesKey, String file, String destFile) throws RuntimeException {            if (!StringUtils.isBlank(aesKey)) {                getInstance(aesKey).encodeFile(file, destFile);            }        }        public static void encryptFile(String aesKey, String b64Key, String file, String destFile)                throws RuntimeException {            if (!StringUtils.isBlank(aesKey) && B64Encrypter.checkAlphabet(b64Key)) {                getInstance(aesKey, b64Key).encodeFile(file, destFile);            }        }        // public static void encryptFileAsyn(String aesKey, String file, String        // destFile)        // throws RuntimeException, FileNotFoundException {        // if (!StringUtils.isBlank(aesKey)) {        // getInstance(aesKey).encodeFileAsyn(file, destFile);        // }        // }        // public static void encryptFileAsyn(String aesKey, String b64Key,        // String file, String destFile)        // throws RuntimeException, FileNotFoundException {        // if (!StringUtils.isBlank(aesKey) &&        // B64Encrypter.checkAlphabet(b64Key)) {        // getInstance(aesKey, b64Key).encodeFileAsyn(file, destFile);        // }        // }        /*************** File decode **************/        public static void decryptFile(String aesKey, String file, String destFile) throws RuntimeException {            if (!StringUtils.isBlank(aesKey)) {                getInstance(aesKey).decodeFile(file, destFile);            }        }        public static void decryptFile(String aesKey, String b64Key, String file, String destFile)                throws RuntimeException {            if (!StringUtils.isBlank(aesKey) && B64Encrypter.checkAlphabet(b64Key)) {                getInstance(aesKey, b64Key).decodeFile(file, destFile);            }        }        // public static void decryptFileAsyn(String aesKey, String file, String        // destFile)        // throws RuntimeException, FileNotFoundException {        // if (!StringUtils.isBlank(aesKey)) {        // getInstance(aesKey).decodeFileAsyn(file, destFile);        // }        // }        //        // public static void decryptFileAsyn(String aesKey, String b64Key,        // String file, String destFile)        // throws RuntimeException, FileNotFoundException {        // if (!StringUtils.isBlank(aesKey) &&        // B64Encrypter.checkAlphabet(b64Key)) {        // getInstance(aesKey, b64Key).decodeFileAsyn(file, destFile);        // }        // }    }    static class Hex {        private static final char[] DIGITS_LOWER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c',                'd', 'e', 'f' };        private static final char[] DIGITS_UPPER = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',                'D', 'E', 'F' };        /**         * 将字节数组转换为十六进制字符数组         *          * @param data         *            byte[]         * @return 十六进制char[]         */        public static char[] encodeHex(byte[] data) {            return encodeHex(data, true);        }        /**         * 将字节数组转换为十六进制字符数组         *          * @param data         *            byte[]         * @param toLowerCase         *            <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式         * @return 十六进制char[]         */        public static char[] encodeHex(byte[] data, boolean toLowerCase) {            return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);        }        /**         * 将字节数组转换为十六进制字符数组         *          * @param data         *            byte[]         * @param toDigits         *            用于控制输出的char[]         * @return 十六进制char[]         */        protected static char[] encodeHex(byte[] data, char[] toDigits) {            int l = data.length;            char[] out = new char[l << 1];            // two characters form the hex value.            for (int i = 0, j = 0; i < l; i++) {                out[j++] = toDigits[(0xF0 & data[i]) >>> 4];                out[j++] = toDigits[0x0F & data[i]];            }            return out;        }        /**         * 将字节数组转换为十六进制字符串         *          * @param data         *            byte[]         * @return 十六进制String         */        public static String encodeHexStr(byte[] data) {            return encodeHexStr(data, true);        }        /**         * 将字节数组转换为十六进制字符串         *          * @param data         *            byte[]         * @param toLowerCase         *            <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式         * @return 十六进制String         */        public static String encodeHexStr(byte[] data, boolean toLowerCase) {            return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);        }        /**         * 将字节数组转换为十六进制字符串         *          * @param data         *            byte[]         * @param toDigits         *            用于控制输出的char[]         * @return 十六进制String         */        protected static String encodeHexStr(byte[] data, char[] toDigits) {            return new String(encodeHex(data, toDigits));        }        /**         * 将十六进制字符数组转换为字节数组         *          * @param data         *            十六进制char[]         * @return byte[]         * @throws RuntimeException         *             如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常         */        public static byte[] decodeHex(char[] data) {            int len = data.length;            if ((len & 0x01) != 0) {                throw new RuntimeException("Odd number of characters.");            }            byte[] out = new byte[len >> 1];            // two characters form the hex value.            for (int i = 0, j = 0; j < len; i++) {                int f = toDigit(data[j], j) << 4;                j++;                f = f | toDigit(data[j], j);                j++;                out[i] = (byte) (f & 0xFF);            }            return out;        }        /**         * 将十六进制字符转换成一个整数         *          * @param ch         *            十六进制char         * @param index         *            十六进制字符在字符数组中的位置         * @return 一个整数         * @throws RuntimeException         *             当ch不是一个合法的十六进制字符时,抛出运行时异常         */        private static int toDigit(char ch, int index) {            int digit = Character.digit(ch, 16);            if (digit == -1) {                throw new RuntimeException("Illegal hexadecimal character " + ch + " at index " + index);            }            return digit;        }        public static String bytes2Hex(byte[] inbuf) {            int i;            String byteStr;            StringBuffer strBuf = new StringBuffer();            for (i = 0; i < inbuf.length; i++) {                byteStr = Integer.toHexString(inbuf[i] & 0x00ff);                if (byteStr.length() != 2) {                    strBuf.append('0').append(byteStr);                } else {                    strBuf.append(byteStr);                }            }            return new String(strBuf);        }        public static byte[] hexToBytes(String inbuf) {            int i;            int len = inbuf.length() / 2;            byte outbuf[] = new byte[len];            for (i = 0; i < len; i++) {                String tmpbuf = inbuf.substring(i * 2, i * 2 + 2);                outbuf[i] = (byte) Integer.parseInt(tmpbuf, 16);            }            return outbuf;        }    }    static class StreamUtils {        public static void close(InputStream inputStream) {            if (inputStream != null) {                try {                    inputStream.close();                } catch (IOException e) {                }            }        }        public static void close(InputStream... inputStreams) {            if (inputStreams != null && inputStreams.length > 0) {                for (InputStream is : inputStreams) {                    if (is != null) {                        try {                            is.close();                        } catch (IOException e) {                        }                    }                }            }        }        public static void close(InputStream inputStream, OutputStream... outputStreams) {            try {                if (inputStream != null)                    inputStream.close();            } catch (IOException e) {            }            if (outputStreams != null && outputStreams.length > 0) {                for (OutputStream os : outputStreams) {                    if (os != null) {                        try {                            os.close();                        } catch (IOException e) {                        }                    }                }            }        }        public static void close(OutputStream outputStream) {            if (outputStream != null) {                try {                    outputStream.close();                } catch (IOException e) {                }            }        }        public static void close(OutputStream... outputStreams) {            if (outputStreams != null && outputStreams.length > 0) {                for (OutputStream os : outputStreams) {                    if (os != null) {                        try {                            os.close();                        } catch (IOException e) {                        }                    }                }            }        }        public static void close(OutputStream outputStream, InputStream... inputStreams) {            if (inputStreams != null && inputStreams.length > 0) {                for (InputStream is : inputStreams) {                    if (is != null) {                        try {                            is.close();                        } catch (IOException e) {                        }                    }                }            }            try {                if (outputStream != null)                    outputStream.close();            } catch (IOException e) {            }        }        public static void close(InputStream inputStream, OutputStream outputStream) {            try {                if (inputStream != null)                    inputStream.close();                if (outputStream != null)                    outputStream.close();            } catch (IOException e) {            }        }        public static void close(AutoCloseable... closeables) {            if (closeables != null && closeables.length > 0) {                for (AutoCloseable ac : closeables) {                    if (ac != null) {                        try {                            ac.close();                        } catch (Exception e) {                        }                    }                }            }        }    }    static class B64Encrypter {        static final String DEFAULT_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";        private static Map<String, B64Encrypter> coderMap = new HashMap<String, B64Encrypter>();        private static char[] defaultEncodeChars = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',                'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',                'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0',                '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };        private static byte[] defaultDecodeChars = new byte[] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,                -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0,                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1,                -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,                49, 50, 51, -1, -1, -1, -1, -1 };        static {            coderMap.put(DEFAULT_ALPHABET, new B64Encrypter(defaultEncodeChars, defaultDecodeChars));        }        private char[] base64EncodeChars;        private byte[] base64DecodeChars;        private B64Encrypter(char[] base64EncodeChars, byte[] base64DecodeChars) {            this.base64EncodeChars = base64EncodeChars;            this.base64DecodeChars = base64DecodeChars;        }        public String encode(byte[] data) {            StringBuffer sb = new StringBuffer();            int len = data.length;            int i = 0;            int b1, b2, b3;            while (i < len) {                b1 = data[i++] & 0xff;                if (i == len) {                    sb.append(base64EncodeChars[b1 >>> 2]);                    sb.append(base64EncodeChars[(b1 & 0x3) << 4]);                    sb.append("**");                    break;                }                b2 = data[i++] & 0xff;                if (i == len) {                    sb.append(base64EncodeChars[b1 >>> 2]);                    sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);                    sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);                    sb.append("*");                    break;                }                b3 = data[i++] & 0xff;                sb.append(base64EncodeChars[b1 >>> 2]);                sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);                sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);                sb.append(base64EncodeChars[b3 & 0x3f]);            }            return sb.toString();        }        public byte[] decode(String str) throws UnsupportedEncodingException {            StringBuffer sb = new StringBuffer();            byte[] data = str.getBytes(Charset.ASCII.VALUE);            int len = data.length;            int i = 0;            int b1, b2, b3, b4;            while (i < len) {                /* b1 */                do {                    b1 = base64DecodeChars[data[i++]];                } while (i < len && b1 == -1);                if (b1 == -1)                    break;                /* b2 */                do {                    b2 = base64DecodeChars[data[i++]];                } while (i < len && b2 == -1);                if (b2 == -1)                    break;                sb.append((char) ((b1 << 2) | ((b2 & 0x30) >>> 4)));                /* b3 */                do {                    b3 = data[i++];                    if (b3 == 61)                        return sb.toString().getBytes(Charset.ISO8859_1.VALUE);                    b3 = base64DecodeChars[b3];                } while (i < len && b3 == -1);                if (b3 == -1)                    break;                sb.append((char) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2)));                /* b4 */                do {                    b4 = data[i++];                    if (b4 == 61)                        return sb.toString().getBytes(Charset.ISO8859_1.VALUE);                    b4 = base64DecodeChars[b4];                } while (i < len && b4 == -1);                if (b4 == -1)                    break;                sb.append((char) (((b3 & 0x03) << 6) | b4));            }            return sb.toString().getBytes(Charset.ISO8859_1.VALUE);        }        public static boolean checkAlphabet(String alphabet) {            if (StringUtils.isBlank(alphabet) || alphabet.length() != 64)                return false;            byte[] temp = new byte[128];            for (int i = 0; i < 64; i++) {                if (temp[alphabet.charAt(i)] > 0) {                    return false;                }                temp[alphabet.charAt(i)] = 1;            }            return true;        }        public static B64Encrypter getInstance() {            return getInstance(DEFAULT_ALPHABET);        }        public static B64Encrypter getInstance(String alphabet) {            if (!checkAlphabet(alphabet))                return null;            B64Encrypter coder = coderMap.get(alphabet);            if (coder == null) {                char[] encodeChar = new char[64];                byte[] decodeChar = new byte[128];                for (int i = 0; i < 64; i++) {                    encodeChar[i] = alphabet.charAt(i);                    decodeChar[encodeChar[i]] = Integer.valueOf(i).byteValue();                }                coder = new B64Encrypter(encodeChar, decodeChar);                coderMap.put(alphabet, coder);            }            return coder;        }        public static String encrypt(byte[] plainText) {            return plainText == null ? null : getInstance().encode(plainText);        }        public static byte[] decrypt(String ciphertext) throws UnsupportedEncodingException {            return StringUtils.isBlank(ciphertext) ? null : getInstance().decode(ciphertext);        }    }}


0 0
原创粉丝点击