Java RSA 加解密

RSA加解密,双方各生成公私钥,并提供给对方公钥,对方用公钥加密数据,己方用保留的私钥进行解密

调用方式:

加密:encrypted=AuiRSA.rsaEncrypt(xml, auibPublicKey, charset_UTF8);

解密:AuiRSA.rsaDecrypt(encrypted, auibPrivateKey, charset_UTF8);    

 

public class AuiRSA {
    
    static final int EIGHTBIT = 8;
    
    static final int FOURBYTE = 4;
    
    static final int SIGN1 = -128;
    
    static final int SIXTEENBIT = 16;
    
    static final int CHUNK_SIZE = 76;

    static final int BASELENGTH = 255;

    static final int LOOKUPLENGTH = 64;
    
    static final byte PAD = (byte) '=';

    static final int TWENTYFOURBITGROUP = 24;

    static final String charset_UTF8="UTF-8";
    
    static final byte[] CHUNK_SEPARATOR = "\r\n".getBytes();
    
    static String auibPublicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDH1Rpgcs5Hd7P18n8eZAWKPmEWAuY2nQ33/iLmyEQw7hSeHTtsEUS4XYNnFz+dQDSZljOTytHp+b7YKw658t3Zhj45gir0UKkCxYdwyvbDuQwW3fOG76prseHfbvgpVCdfpD12d/IsZMIiSu4q5s2J4WvzJOLMMUradz6lBXABiQIDAQAB"; 
    
    static String auibPrivateKey=""; 

    static String self_publicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGvcSjtMQQM+iPjkcpk+0VG6VjiskbAr8fX1EZxRaAqOls9qZdzFDh9lQ0kcBqu2MCKtVFcvMC/GAfNBJsd0e3IO7JVx7K8FI3YnCr4h6l2NHrj3LxoU1Mb240klrmIFwh9u4mQb7gvo4HLQ0vQ0RJZOYKerxOSumuzYk4lNL6rQIDAQAB";
    
    static String self_privateKey="MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMa9xKO0xBAz6I+ORymT7RUbpWOKyRsCvx9fURnFFoCo6Wz2pl3MUOH2VDSRwGq7YwIq1UVy8wL8YB80Emx3R7cg7slXHsrwUjdicKviHqXY0euPcvGhTUxvbjSSWuYgXCH27iZBvuC+jgctDS9DRElk5gp6vE5K6a7NiTiU0vqtAgMBAAECgYEAhj1qFBWmlTcqr8SvppLngelxlkIJQrhhNiSg2CI6596wBMy5ZQP74hULnZKRgMZfwvgBpG5XXL3xg0Id66vKAOIqvVxW+F4LIS60kTHb8pwAbL14/FLd1WF2fTtWUSQKFAtaKUPcnl5c8tRvNlIzb+udRXx8c1n62FQ4/Jsx43UCQQD/Wb5dn44hrdNeam3rxWIZxslVI22mnLlG2GMUlmo/2EQzHxrIuF3X2ioQzkCgZIOdrMMmOcnwffvJzxRnFRdTAkEAxz8qrsz8sKRz92g5ugNNVb0w0yu5pa1r75f4rbHQNbFlYywS5G93n8/IiaTvirJINyp3sgu+r0rMKLbD1k9l/wJAKbWuC7rxS30KRqTZ2aY/NPiskFSeJ5X4CaN047sCFfWshjExfdHnukdvkZkvI0Pn38yFf+v2mWrqwvcpXQEr8wJBAJWOs5I8KhzJhIacRGB85ArMlR6dfp9++jsBHtf6VahH/SugxJmVlfxucj/nfyrjwdMu3GPX7w0THwYckgmG1a8CQQDzG8eSb8rifkaVU/hx9KfD21VC4f2RloLJ7Z1BjEw4E29IpDQdyF+28yuAQ8aIrc3bAFBHRfgM3UG9G7103hU5";

    public static final String SIGN_TYPE        = "sign_type";

    public static final String SIGN_TYPE_RSA    = "RSA";

    public static final String SIGN_ALGORITHMS  = "SHA1WithRSA";

    public static final String SIGN             = "sign";
    
    public static final String ALIPAY_SDK       = "alipay_sdk";

    public static final String CHARSET          = "charset";

    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static final String DATE_TIMEZONE    = "GMT+8";

    public static final String CHARSET_UTF8     = "UTF-8";

    public static final String CHARSET_GBK      = "GBK";

    private static final int MAX_ENCRYPT_BLOCK = 117;

    private static final int MAX_DECRYPT_BLOCK = 128;

    private static final int DEFAULT_BUFFER_SIZE = 8192;
    
    private static byte[] base64Alphabet = new byte[BASELENGTH];
     
    private static byte[] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
        
    public static String getSignContent(Map<String, String> sortedParams) {
        StringBuffer content = new StringBuffer();
        List<String> keys = new ArrayList<String>(sortedParams.keySet());
        Collections.sort(keys);
        int index = 0;
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = sortedParams.get(key);
            if (AuiRSA.areNotEmpty(key, value)) {
                content.append((index == 0 ? "" : "&") + key + "=" + value);
                index++;
            }
        }
        return content.toString();
    }

    public static String rsaSign(String content, String privateKey, String charset) throws Exception {
        try {
            PrivateKey priKey = getPrivateKeyFromPKCS8(AuiRSA.SIGN_TYPE_RSA,new ByteArrayInputStream(privateKey.getBytes()));
            java.security.Signature signature = java.security.Signature.getInstance(AuiRSA.SIGN_ALGORITHMS);
            signature.initSign(priKey);
            if (AuiRSA.isEmpty(charset)) {
                signature.update(content.getBytes());
            } else {
                signature.update(content.getBytes(charset));
            }
            byte[] signed = signature.sign();
            return new String(AuiRSA.encodeBase64(signed));
        } catch (Exception e) {
            throw new Exception("RSAcontent = " + content + "; charset = " + charset, e);
        }
    }

    public static PrivateKey getPrivateKeyFromPKCS8(String algorithm, InputStream ins) throws Exception {
        if (ins == null || AuiRSA.isEmpty(algorithm)) {
            return null;
        }
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        byte[] encodedKey = AuiRSA.readText(ins).getBytes();
        encodedKey = AuiRSA.decodeBase64(encodedKey);
        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
    }

    public static String getSignCheckContentV2(Map<String, String> params) {
        if (params == null) {
            return null;
        }
        params.remove("sign");
        StringBuffer content = new StringBuffer();
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            content.append((i == 0 ? "" : "&") + key + "=" + value);
        }
        return content.toString();
    }

    public static boolean rsaCheckContent(String content, String sign, String publicKey,String charset) throws Exception {
        try {
            PublicKey pubKey = getPublicKeyFromX509("RSA", new ByteArrayInputStream(publicKey.getBytes()));
            java.security.Signature signature = java.security.Signature.getInstance(AuiRSA.SIGN_ALGORITHMS);
            signature.initVerify(pubKey);
            if (AuiRSA.isEmpty(charset)) {
                signature.update(content.getBytes());
            } else {
                signature.update(content.getBytes(charset));
            }
            return signature.verify(AuiRSA.decodeBase64(sign.getBytes()));
        } catch (Exception e) {
            throw new Exception("RSAcontent = " + content + ",sign=" + sign + ",charset = " + charset, e);
        }
    }

    public static PublicKey getPublicKeyFromX509(String algorithm, InputStream ins) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        StringWriter writer = new StringWriter();
        AuiRSA.io(new InputStreamReader(ins), writer);
        byte[] encodedKey = writer.toString().getBytes();
        encodedKey = AuiRSA.decodeBase64(encodedKey);
        return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
    }

    /**
     * 公钥加密
     * @param content   待加密内容
     * @param publicKey 公钥
     * @param charset   字符集,如UTF-8, GBK, GB2312
     * @return 密文内容
     * @throws AlipayApiException
     */
    public static String rsaEncrypt(String content, String publicKey, String charset) throws Exception {
        try {
            PublicKey pubKey = getPublicKeyFromX509(AuiRSA.SIGN_TYPE_RSA,new ByteArrayInputStream(publicKey.getBytes()));
            Cipher cipher = Cipher.getInstance(AuiRSA.SIGN_TYPE_RSA);
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            byte[] data = AuiRSA.isEmpty(charset) ? content.getBytes() : content.getBytes(charset);
            int inputLen = data.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段加密  
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                    cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(data, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_ENCRYPT_BLOCK;
            }
            byte[] encryptedData = AuiRSA.encodeBase64(out.toByteArray());
            out.close();
            return AuiRSA.isEmpty(charset) ? new String(encryptedData) : new String(encryptedData, charset);
        } catch (Exception e) {
            throw new Exception("EncryptContent = " + content + ",charset = " + charset, e);
        }
    }

    /**
     * 私钥解密
     * @param content    待解密内容
     * @param privateKey 私钥
     * @param charset    字符集,如UTF-8, GBK, GB2312
     * @return 明文内容
     * @throws AlipayApiException
     */
    public static String rsaDecrypt(String content, String privateKey, String charset) throws Exception {
        try {
            PrivateKey priKey = getPrivateKeyFromPKCS8(AuiRSA.SIGN_TYPE_RSA,new ByteArrayInputStream(privateKey.getBytes()));
            Cipher cipher = Cipher.getInstance(AuiRSA.SIGN_TYPE_RSA);
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            byte[] encryptedData = AuiRSA.isEmpty(charset) ? AuiRSA.decodeBase64(content.getBytes()) : AuiRSA.decodeBase64(content.getBytes(charset));
            int inputLen = encryptedData.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段解密  
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                    cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_DECRYPT_BLOCK;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();
            return AuiRSA.isEmpty(charset) ? new String(decryptedData) : new String(decryptedData, charset);
        } catch (Exception e) {
            throw new Exception("EncodeContent = " + content + ",charset = " + charset, e);
        }
    }

    public static void io(InputStream in, OutputStream out) throws IOException {
        io(in, out, -1);
    }

    public static void io(InputStream in, OutputStream out, int bufferSize) throws IOException {
        if (bufferSize == -1) {
            bufferSize = DEFAULT_BUFFER_SIZE;
        }
        byte[] buffer = new byte[bufferSize];
        int amount;
        while ((amount = in.read(buffer)) >= 0) {
            out.write(buffer, 0, amount);
        }
    }

    public static void io(Reader in, Writer out) throws IOException {
        io(in, out, -1);
    }

    public static void io(Reader in, Writer out, int bufferSize) throws IOException {
        if (bufferSize == -1) {
            bufferSize = DEFAULT_BUFFER_SIZE >> 1;
        }
        char[] buffer = new char[bufferSize];
        int amount;
        while ((amount = in.read(buffer)) >= 0) {
            out.write(buffer, 0, amount);
        }
    }

    public static OutputStream synchronizedOutputStream(OutputStream out) {
        return new SynchronizedOutputStream(out);
    }

    public static OutputStream synchronizedOutputStream(OutputStream out, Object lock) {
        return new SynchronizedOutputStream(out, lock);
    }

    public static String readText(InputStream in) throws IOException {
        return readText(in, null, -1);
    }

    public static String readText(InputStream in, String encoding) throws IOException {
        return readText(in, encoding, -1);
    }

    public static String readText(InputStream in, String encoding, int bufferSize) throws IOException {
        Reader reader = (encoding == null) ? new InputStreamReader(in) : new InputStreamReader(in,encoding);
        return readText(reader, bufferSize);
    }

    public static String readText(Reader reader) throws IOException {
        return readText(reader, -1);
    }

    public static String readText(Reader reader, int bufferSize) throws IOException {
        StringWriter writer = new StringWriter();
        io(reader, writer, bufferSize);
        return writer.toString();
    }

    private static class SynchronizedOutputStream extends OutputStream {
        private OutputStream out;
        private Object       lock;
        SynchronizedOutputStream(OutputStream out) {
            this(out, out);
        }
        SynchronizedOutputStream(OutputStream out, Object lock) {
            this.out = out;
            this.lock = lock;
        }
        public void write(int datum) throws IOException {
            synchronized (lock) {
                out.write(datum);
            }
        }
        public void write(byte[] data) throws IOException {
            synchronized (lock) {
                out.write(data);
            }
        }
        public void write(byte[] data, int offset, int length) throws IOException {
            synchronized (lock) {
                out.write(data, offset, length);
            }
        }
        public void flush() throws IOException {
            synchronized (lock) {
                out.flush();
            }
        }
        public void close() throws IOException {
            synchronized (lock) {
                out.close();
            }
        }
    }

    /**
     * 检查指定的字符串是否为空。
     * <ul>
     * <li>SysUtils.isEmpty(null) = true</li>
     * <li>SysUtils.isEmpty("") = true</li>
     * <li>SysUtils.isEmpty("   ") = true</li>
     * <li>SysUtils.isEmpty("abc") = false</li>
     * </ul>
     * @param value 待检查的字符串
     * @return true/false
     */
    public static boolean isEmpty(String value) {
        int strLen;
        if (value == null || (strLen = value.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(value.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 检查对象是否为数字型字符串,包含负数开头的。
     */
    public static boolean isNumeric(Object obj) {
        if (obj == null) {
            return false;
        }
        char[] chars = obj.toString().toCharArray();
        int length = chars.length;
        if(length < 1)
            return false;

        int i = 0;
        if(length > 1 && chars[0] == '-')
            i = 1;
        
        for (; i < length; i++) {
            if (!Character.isDigit(chars[i])) {
                return false;
            }
        }
        return true;
    }

    /**
     * 检查指定的字符串列表是否不为空。
     */
    public static boolean areNotEmpty(String... values) {
        boolean result = true;
        if (values == null || values.length == 0) {
            result = false;
        } else {
            for (String value : values) {
                result &= !isEmpty(value);
            }
        }
        return result;
    }

    /**
     * 把通用字符编码的字符串转化为汉字编码。
     */
    public static String unicodeToChinese(String unicode) {
        StringBuilder out = new StringBuilder();
        if (!isEmpty(unicode)) {
            for (int i = 0; i < unicode.length(); i++) {
                out.append(unicode.charAt(i));
            }
        }
        return out.toString();
    }

    /**
     * 过滤不可见字符
     */
    public static String stripNonValidXMLCharacters(String input) {
        if (input == null || ("".equals(input)))
            return "";
        StringBuilder out = new StringBuilder();
        char current;
        for (int i = 0; i < input.length(); i++) {
            current = input.charAt(i);
            if ((current == 0x9) || (current == 0xA) || (current == 0xD)
                    || ((current >= 0x20) && (current <= 0xD7FF))
                    || ((current >= 0xE000) && (current <= 0xFFFD))
                    || ((current >= 0x10000) && (current <= 0x10FFFF)))
                out.append(current);
        }
        return out.toString();
    }

    
    /**
     * @Description: 取得唯一不重复的值
     * @return String
     */
    public static String getGuid() {
        return java.util.UUID.randomUUID().toString();
    }

    /**  
     * @Description: MD5加密 
     * @param originstr
     * @return String 
     */
    public static String ecodeByMD5(String originstr) {
        String result = null;
        // 用来将字节转换成 16 进制表示的字�?
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f' };
        if (originstr != null) {
            try {
                // 返回实现指定摘要算法�?MessageDigest 对象
                MessageDigest md = MessageDigest.getInstance("MD5");
                // 使用utf-8编码将originstr字符串编码并保存到source字节数组
                byte[] source = originstr.getBytes("utf-8");
                // 使用指定�?byte 数组更新摘要
                md.update(source);
                // 通过执行诸如填充之类的最终操作完成哈希计算,结果是一�?28位的长整�?
                byte[] tmp = md.digest();
                // �?6进制数表示需�?2�?
                char[] str = new char[32];
                for (int i = 0, j = 0; i < 16; i++) {
                    // j表示转换结果中对应的字符位置
                    // 从第�?��字节�?��,对 MD5 的每�?��字节
                    // 转换�?16 进制字符
                    byte b = tmp[i];
                    // 取字节中�?4 位的数字转换
                    // 无符号右移运算符>>> ,它总是在左边补0
                    // 0x代表它后面的是十六进制的数字. f转换成十进制就是15
                    str[j++] = hexDigits[b >>> 4 & 0xf];
                    // 取字节中�?4 位的数字转换
                    str[j++] = hexDigits[b & 0xf];
                }
                result = new String(str);// 结果转换成字符串用于返回
            } catch (NoSuchAlgorithmException e) {
                // 当请求特定的加密算法而它在该环境中不可用时抛出此异常
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                // 不支持字符编码异�?
                e.printStackTrace();
            }
        }
        return result;
    }
    /**
     * 按指定编码MD5加密 
     * @Description: 按指定编码MD5加密 
     * @param originstr 
     * @param encoding
     * @return String 
     */
    public static String ecodeByMD5(String originstr,String encoding) {
        String result = null;
        // 用来将字节转换成 16 进制表示的字�?
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f' };
        if (originstr != null) {
            try {
                // 返回实现指定摘要算法�?MessageDigest 对象
                MessageDigest md = MessageDigest.getInstance("MD5");
                // 使用utf-8编码将originstr字符串编码并保存到source字节数组
                if(encoding==null || encoding.trim().length()==0){
                    encoding="utf-8";
                }
                byte[] source = originstr.getBytes(encoding);
                // 使用指定�?byte 数组更新摘要
                md.update(source);
                // 通过执行诸如填充之类的最终操作完成哈希计算,结果是一�?28位的长整�?
                byte[] tmp = md.digest();
                // �?6进制数表示需�?2�?
                char[] str = new char[32];
                for (int i = 0, j = 0; i < 16; i++) {
                    // j表示转换结果中对应的字符位置
                    // 从第�?��字节�?��,对 MD5 的每�?��字节
                    // 转换�?16 进制字符
                    byte b = tmp[i];
                    // 取字节中�?4 位的数字转换
                    // 无符号右移运算符>>> ,它总是在左边补0
                    // 0x代表它后面的是十六进制的数字. f转换成十进制就是15
                    str[j++] = hexDigits[b >>> 4 & 0xf];
                    // 取字节中�?4 位的数字转换
                    str[j++] = hexDigits[b & 0xf];
                }
                result = new String(str);// 结果转换成字符串用于返回
            } catch (NoSuchAlgorithmException e) {
                // 当请求特定的加密算法而它在该环境中不可用时抛出此异常
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                // 不支持字符编码异�?
                e.printStackTrace();
            }
        }
        return result;
    }

    static {
        for (int i = 0; i < BASELENGTH; i++) {
            base64Alphabet[i] = (byte) -1;
        }
        for (int i = 'Z'; i >= 'A'; i--) {
            base64Alphabet[i] = (byte) (i - 'A');
        }
        for (int i = 'z'; i >= 'a'; i--) {
            base64Alphabet[i] = (byte) (i - 'a' + 26);
        }
        for (int i = '9'; i >= '0'; i--) {
            base64Alphabet[i] = (byte) (i - '0' + 52);
        }

        base64Alphabet['+'] = 62;
        base64Alphabet['/'] = 63;

        for (int i = 0; i <= 25; i++) {
            lookUpBase64Alphabet[i] = (byte) ('A' + i);
        }

        for (int i = 26, j = 0; i <= 51; i++, j++) {
            lookUpBase64Alphabet[i] = (byte) ('a' + j);
        }

        for (int i = 52, j = 0; i <= 61; i++, j++) {
            lookUpBase64Alphabet[i] = (byte) ('0' + j);
        }

        lookUpBase64Alphabet[62] = (byte) '+';
        lookUpBase64Alphabet[63] = (byte) '/';
    }

    private static boolean isBase64(byte octect) {
        if (octect == PAD) {
            return true;
        } else if (base64Alphabet[octect] == -1) {
            return false;
        } else {
            return true;
        }
    }

    public static boolean isArrayByteBase64(byte[] arrayOctect) {
        arrayOctect = discardWhitespace(arrayOctect);
        int length = arrayOctect.length;
        if (length == 0) {
            return true;
        }
        for (int i = 0; i < length; i++) {
            if (!isBase64(arrayOctect[i])) {
                return false;
            }
        }
        return true;
    }

    public static byte[] encodeBase64(byte[] binaryData) {
        return encodeBase64(binaryData, false);
    }

    public static byte[] encodeBase64Chunked(byte[] binaryData) {
        return encodeBase64(binaryData, true);
    }

    public Object decode(Object pObject) throws Exception {
        if (!(pObject instanceof byte[])) {
            throw new Exception("Parameter supplied to Base64 decode is not a byte[]");
        }
        return decode((byte[]) pObject);
    }

    public byte[] decode(byte[] pArray) {
        return decodeBase64(pArray);
    }

    public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) {
        int lengthDataBits = binaryData.length * EIGHTBIT;
        int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
        int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
        byte encodedData[] = null;
        int encodedDataLength = 0;
        int nbrChunks = 0;
        if (fewerThan24bits != 0) {
            encodedDataLength = (numberTriplets + 1) * 4;
        } else {
            encodedDataLength = numberTriplets * 4;
        }
        if (isChunked) {
            nbrChunks = (CHUNK_SEPARATOR.length == 0 ? 0 : (int) Math.ceil((float) encodedDataLength / CHUNK_SIZE));
            encodedDataLength += nbrChunks * CHUNK_SEPARATOR.length;
        }
        encodedData = new byte[encodedDataLength];
        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
        int encodedIndex = 0;
        int dataIndex = 0;
        int i = 0;
        int nextSeparatorIndex = CHUNK_SIZE;
        int chunksSoFar = 0;
        for (i = 0; i < numberTriplets; i++) {
            dataIndex = i * 3;
            b1 = binaryData[dataIndex];
            b2 = binaryData[dataIndex + 1];
            b3 = binaryData[dataIndex + 2];
            l = (byte) (b2 & 0x0f);
            k = (byte) (b1 & 0x03);
            byte val1 = ((b1 & SIGN1) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
            byte val2 = ((b2 & SIGN1) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
            byte val3 = ((b3 & SIGN1) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);

            encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
            encodedData[encodedIndex + 1] = lookUpBase64Alphabet[val2 | (k << 4)];
            encodedData[encodedIndex + 2] = lookUpBase64Alphabet[(l << 2) | val3];
            encodedData[encodedIndex + 3] = lookUpBase64Alphabet[b3 & 0x3f];
            encodedIndex += 4;

            if (isChunked) {
                if (encodedIndex == nextSeparatorIndex) {
                    System.arraycopy(CHUNK_SEPARATOR,0,encodedData,encodedIndex,CHUNK_SEPARATOR.length);
                    chunksSoFar++;
                    nextSeparatorIndex = (CHUNK_SIZE * (chunksSoFar + 1)) + (chunksSoFar * CHUNK_SEPARATOR.length);
                    encodedIndex += CHUNK_SEPARATOR.length;
                }
            }
        }

        dataIndex = i * 3;

        if (fewerThan24bits == EIGHTBIT) {
            b1 = binaryData[dataIndex];
            k = (byte) (b1 & 0x03);
            byte val1 = ((b1 & SIGN1) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
            encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
            encodedData[encodedIndex + 1] = lookUpBase64Alphabet[k << 4];
            encodedData[encodedIndex + 2] = PAD;
            encodedData[encodedIndex + 3] = PAD;
        } else if (fewerThan24bits == SIXTEENBIT) {
            b1 = binaryData[dataIndex];
            b2 = binaryData[dataIndex + 1];
            l = (byte) (b2 & 0x0f);
            k = (byte) (b1 & 0x03);

            byte val1 = ((b1 & SIGN1) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
            byte val2 = ((b2 & SIGN1) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);

            encodedData[encodedIndex] = lookUpBase64Alphabet[val1];
            encodedData[encodedIndex + 1] = lookUpBase64Alphabet[val2 | (k << 4)];
            encodedData[encodedIndex + 2] = lookUpBase64Alphabet[l << 2];
            encodedData[encodedIndex + 3] = PAD;
        }

        if (isChunked) {
            if (chunksSoFar < nbrChunks) {
                System.arraycopy(CHUNK_SEPARATOR,0,encodedData,encodedDataLength - CHUNK_SEPARATOR.length,CHUNK_SEPARATOR.length);
            }
        }
        return encodedData;
    }

    public static byte[] decodeBase64(byte[] base64Data) {
        base64Data = discardNonBase64(base64Data);
        if (base64Data.length == 0) {
            return new byte[0];
        }
        int numberQuadruple = base64Data.length / FOURBYTE;
        byte decodedData[] = null;
        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0;
        int encodedIndex = 0;
        int dataIndex = 0;
        {
            int lastData = base64Data.length;
            while (base64Data[lastData - 1] == PAD) {
                if (--lastData == 0) {
                    return new byte[0];
                }
            }
            decodedData = new byte[lastData - numberQuadruple];
        }
        
        for (int i = 0; i < numberQuadruple; i++) {
            dataIndex = i * 4;
            marker0 = base64Data[dataIndex + 2];
            marker1 = base64Data[dataIndex + 3];
            
            b1 = base64Alphabet[base64Data[dataIndex]];
            b2 = base64Alphabet[base64Data[dataIndex + 1]];
            
            if (marker0 != PAD && marker1 != PAD) {
                b3 = base64Alphabet[marker0];
                b4 = base64Alphabet[marker1];
                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
                decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
                decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
            } else if (marker0 == PAD) {
                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
            } else if (marker1 == PAD) {
                b3 = base64Alphabet[marker0];
                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
                decodedData[encodedIndex + 1] =  (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
            }
            encodedIndex += 3;
        }
        return decodedData;
    }
    
    static byte[] discardWhitespace(byte[] data) {
        byte groomedData[] = new byte[data.length];
        int bytesCopied = 0;
        
        for (int i = 0; i < data.length; i++) {
            switch (data[i]) {
            case (byte) ' ' :
            case (byte) '\n' :
            case (byte) '\r' :
            case (byte) '\t' :
                    break;
            default:
                    groomedData[bytesCopied++] = data[i];
            }
        }

        byte packedData[] = new byte[bytesCopied];

        System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);

        return packedData;
    }

    static byte[] discardNonBase64(byte[] data) {
        byte groomedData[] = new byte[data.length];
        int bytesCopied = 0;

        for (int i = 0; i < data.length; i++) {
            if (isBase64(data[i])) {
                groomedData[bytesCopied++] = data[i];
            }
        }
        byte packedData[] = new byte[bytesCopied];
        System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
        return packedData;
    }

    public Object encode(Object pObject) throws Exception {
        if (!(pObject instanceof byte[])) {
            throw new Exception("Parameter supplied to Base64 encode is not a byte[]");
        }
        return encode((byte[]) pObject);
    }

    public byte[] encode(byte[] pArray) {
        return encodeBase64(pArray, false);
    }

    public String put(String key, Object value) {
        String strValue;
        if (value == null) {
            strValue = null;
        } else if (value instanceof String) {
            strValue = (String) value;
        } else if (value instanceof Integer) {
            strValue = ((Integer) value).toString();
        } else if (value instanceof Long) {
            strValue = ((Long) value).toString();
        } else if (value instanceof Float) {
            strValue = ((Float) value).toString();
        } else if (value instanceof Double) {
            strValue = ((Double) value).toString();
        } else if (value instanceof Boolean) {
            strValue = ((Boolean) value).toString();
        } else if (value instanceof Date) {
            DateFormat format = new SimpleDateFormat(AuiRSA.DATE_TIME_FORMAT);
            format.setTimeZone(TimeZone.getTimeZone(AuiRSA.DATE_TIMEZONE));
            strValue = format.format((Date) value);
        } else {
            strValue = value.toString();
        }
        return this.put(key, strValue);
    }
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值