// Path: src/main/java/com/wind/common/StringUtil.java
// public class StringUtil {
// 
//     /**
//      * 判断字符串是否为null或空字符串
//      * @param str
//      * @return
//      */
//     public static boolean isNotBlank(String str){
//         return str != null && !"".equals(str.trim());
//     }
// 
// 
//     /**
//      * url编码
//      * @param str
//      * @return
//      */
//     public static String encodeUrl(String str){
//         String s = null;
//         try {
//             s = URLEncoder.encode(str, Constants.UTF8);
//         } catch (UnsupportedEncodingException e) {
//             e.printStackTrace();
//         }
// 
//         return s;
//     }
// 
//     /**
//      * url解码
//      * @param str
//      * @return
//      */
//     public static String decodeUrl(String str){
//         String s = null;
//         try {
//             s = URLDecoder.decode(str, Constants.UTF8);
//         } catch (UnsupportedEncodingException e) {
//             e.printStackTrace();
//         }
//         return s;
//     }
// 
// 
//     /**
//      * 字符串分隔 StringTokenizer效率是三种分隔方法中最快的
//      * @param str
//      * @param sign
//      * @return
//      */
//     public static String[] split(String str, String sign){
//         if(str == null){
//             return new String[]{};
//         }
//         StringTokenizer token = new StringTokenizer(str,sign);
//         String[] strArr = new String[token.countTokens()];
//         int i = 0;
//         while(token.hasMoreElements()){
//             strArr[i] = token.nextElement().toString();
//             i++;
//         }
//         return strArr;
//     }
// 
//     /**
//      * 字符串拼接
//      * @param sign
//      * @param strArr
//      * @return
//      */
//     public static String joinStr(String sign, String... strArr){
//         Optional<String> optional  = Arrays.stream(strArr).filter(Objects::nonNull
//         ).reduce((a, b) -> a + sign + b);
//         return optional.orElse("");
//     }
// }


import com.wind.common.StringUtil;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
     * @param a
     *            the first byte array
     * @param b
     *            the second byte array
     * @return true if both byte arrays are the same, false if not
     */
    private static boolean slowEquals(byte[] a, byte[] b) {
        int diff = a.length ^ b.length;
        for (int i = 0; i < a.length && i < b.length; i++) {
            diff |= a[i] ^ b[i];
        }
        return diff == 0;
    }

    /**
     * Computes the PBKDF2 hash of a password.
     *
     * @param password
     *            the password to hash.
     * @param salt
     *            the salt
     * @param iterations
     *            the iteration count (slowness factor)
     * @param bytes
     *            the length of the hash to compute in bytes
     * @return the PBDKF2 hash of the password
     */
    private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
// Path: src/main/java/com/wind/common/StringUtil.java
// public class StringUtil {
// 
//     /**
//      * 判断字符串是否为null或空字符串
//      * @param str
//      * @return
//      */
//     public static boolean isNotBlank(String str){
//         return str != null && !"".equals(str.trim());
//     }
// 
// 
//     /**
//      * url编码
//      * @param str
//      * @return
//      */
//     public static String encodeUrl(String str){
//         String s = null;
//         try {
//             s = URLEncoder.encode(str, Constants.UTF8);
//         } catch (UnsupportedEncodingException e) {
//             e.printStackTrace();
//         }
// 
//         return s;
//     }
// 
//     /**
//      * url解码
//      * @param str
//      * @return
//      */
//     public static String decodeUrl(String str){
//         String s = null;
//         try {
//             s = URLDecoder.decode(str, Constants.UTF8);
//         } catch (UnsupportedEncodingException e) {
//             e.printStackTrace();
//         }
//         return s;
//     }
// 
// 
//     /**
//      * 字符串分隔 StringTokenizer效率是三种分隔方法中最快的
//      * @param str
//      * @param sign
//      * @return
//      */
//     public static String[] split(String str, String sign){
//         if(str == null){
//             return new String[]{};
//         }
//         StringTokenizer token = new StringTokenizer(str,sign);
//         String[] strArr = new String[token.countTokens()];
//         int i = 0;
//         while(token.hasMoreElements()){
//             strArr[i] = token.nextElement().toString();
//             i++;
//         }
//         return strArr;
//     }
// 
//     /**
//      * 字符串拼接
//      * @param sign
//      * @param strArr
//      * @return
//      */
//     public static String joinStr(String sign, String... strArr){
//         Optional<String> optional  = Arrays.stream(strArr).filter(Objects::nonNull
//         ).reduce((a, b) -> a + sign + b);
//         return optional.orElse("");
//     }
// }


// Path: src/main/java/com/wind/encrypt/CryptoUtil.java
import com.wind.common.StringUtil;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

     * @param a
     *            the first byte array
     * @param b
     *            the second byte array
     * @return true if both byte arrays are the same, false if not
     */
    private static boolean slowEquals(byte[] a, byte[] b) {
        int diff = a.length ^ b.length;
        for (int i = 0; i < a.length && i < b.length; i++) {
            diff |= a[i] ^ b[i];
        }
        return diff == 0;
    }

    /**
     * Computes the PBKDF2 hash of a password.
     *
     * @param password
     *            the password to hash.
     * @param salt
     *            the salt
     * @param iterations
     *            the iteration count (slowness factor)
     * @param bytes
     *            the length of the hash to compute in bytes
     * @return the PBDKF2 hash of the password
     */
    private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
        SecretKeyFactory skf = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);