package com.njcn.utils;


import static java.lang.Integer.parseInt;

import java.io.*;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.njcn.mapper.user.ManageListMapper;
import com.njcn.pojo.commons.*;
import com.njcn.pojo.user.ManageList;
import com.njcn.utils.SM.SM2;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.shiro.session.Session;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.njcn.pojo.data.EventDetail;
import com.njcn.shiro.session.UserSessionManager;
import com.njcn.shiro.token.TokenManager;
import com.njcn.sso.pojo.user.User;
import com.njcn.sso.shiro.session.SessionStatus;
import com.njcn.utils.SM.SM3Digest;

import jcifs.smb.NtlmPasswordAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ReflectionUtils;

public class PubUtils {

    // 日志记录
    private static final Logger logger = LoggerFactory.getLogger(PubUtils.class);

    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private AppConfig appConfig;

    @Autowired
    ManageListMapper alm;

    /*************************
     * 工作秘钥
     *
     **************************/
    public static String GetSecretKey() {
        Random r = new Random();// 生成随机数
        String[] code = {"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", "1", "2", "3", "4", "5", "6", "7",
                "8", "9"};
        String str = "";

        // 如果想随即10位大小写字母，把16改为 10 即可
        for (int i = 0; i < 16; i++) {
            str += code[r.nextInt(code.length - 1)];
        }
        return str.replaceAll(",", "");
    }

    /*************************
     * 随机生成推荐码(6位)
     *
     **************************/
    public static String referralCode() {
        Random r = new Random();// 生成随机数
        String[] code = {"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", "1", "2", "3", "4", "5", "6", "7",
                "8", "9"};
        String str = "";

        // 如果想随即10位大小写字母，把16改为 10 即可
        for (int i = 0; i < 6; i++) {
            str += code[r.nextInt(code.length - 1)];
        }
        return str.replaceAll(",", "");
    }

    /**
     * 获取系统IP_CMD
     */
    public static String getLocalIPForCMD() {
        StringBuilder sb = new StringBuilder();
        String command = "cmd.exe /c ipconfig | findstr IPv4";
        try {
            Process p = Runtime.getRuntime().exec(command);
            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            while ((line = br.readLine()) != null) {
                line = line.substring(line.lastIndexOf(":") + 2, line.length());
                sb.append(line);
                break;
            }
            br.close();
            p.destroy();
        } catch (IOException e) {
            logger.error("获取系统Ip");
        }
        return sb.toString();
    }


    /**
     * 比较两个日期之间的大小
     *
     * @return d1 大于 d2 返回true
     */
    public static boolean compareDate(Date d1, Date d2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(d1);
        c2.setTime(d2);

        int result = c1.compareTo(c2);
        if (result >= 0)
            return true;
        else
            return false;
    }


    /****
     * ***** ***** 验证IP是否属于某个IP段 ipSection IP段（以'-'分隔） ip 所验证的IP号码 ***** *****
     *****/
    public static boolean ipExistsInRange(String ip, String ipSection) {
        ipSection = ipSection.trim();
        ip = ip.trim();
        int idx = ipSection.indexOf('-');
        String beginIP = ipSection.substring(0, idx);
        String endIP = ipSection.substring(idx + 1);
        return getIp2long(beginIP) <= getIp2long(ip) && getIp2long(ip) <= getIp2long(endIP);
    }

    private static long getIp2long(String ip) {
        ip = ip.trim();
        String[] ips = ip.split("\\.");
        long ip2long = 0L;
        for (int i = 0; i < 4; ++i) {
            ip2long = ip2long << 8 | parseInt(ips[i]);
        }
        return ip2long;
    }

    private static long getIp2long2(String ip) {
        ip = ip.trim();
        String[] ips = ip.split("\\.");
        long ip1 = parseInt(ips[0]);
        long ip2 = parseInt(ips[1]);
        long ip3 = parseInt(ips[2]);
        long ip4 = parseInt(ips[3]);
        long ip2long = 1L * ip1 * 256 * 256 * 256 + ip2 * 256 * 256 + ip3 * 256 + ip4;
        return ip2long;
    }

    public static boolean WriteFile(File filename, String data) {
        boolean flag = false;
        try {
            PrintStream ps = new PrintStream(new FileOutputStream(filename));
            ps.append(data);// 在已有的基础上添加字符串
            ps.close();
            flag = true;
        } catch (Exception e) {
            logger.error("读写文件发生异常，异常是" + e.getMessage());
        }
        return flag;
    }

    /**
     * 字符串转日期函数 strTime:需要转换的字符串 strFormat:转换的格式(yyyy-MM-dd HH:mm:ss)
     */
    public static Date string2Date(String strTime, String strFormat) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat(strFormat);
        return format.parse(strTime);
    }

    /**
     * 日期转字符串函数 date:需要转换的日期 strFormat:转换的格式(yyyy-MM-dd HH:mm:ss)
     */
    public static String date2String(Date date, String strFormat) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat(strFormat);

        return format.format(date);
    }

    /**
     * 毫秒转时间 ms:需要转换的毫秒时间
     */
    public static Date ms2Date(Long ms) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(ms);

        return c.getTime();
    }

    public static String getMs(long ms) {
        //得到一个NumberFormat的实例
        NumberFormat nf = NumberFormat.getInstance();
        //设置是否使用分组
        nf.setGroupingUsed(false);
        //设置最大整数位数
        nf.setMaximumIntegerDigits(3);
        //设置最小整数位数
        nf.setMinimumIntegerDigits(3);
        //输出测试语句
        return nf.format(ms).toString();
    }


    /**
     * 检测前台传来的时间参数是否合法
     *
     * @param startTime  起始时间
     * @param endTime    截止时间
     * @param methodName 方法名方便日志记录
     */
    public static DatePojo validateDate(String startTime, String endTime, String methodName) {
        DatePojo datePojo = new DatePojo();
        Date sTime;
        Date eTime;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            sTime = sdf.parse(startTime);
            datePojo.setStartTime(sTime);
            //判断截止时间是否为当天
            boolean flag = judgeEndTime(endTime, sdf);
            if (flag) {
                eTime = new Date();
            } else {
                endTime = endTime + " 23:59:59";
                eTime = sdfs.parse(endTime);
            }
            datePojo.setEndTime(eTime);
            datePojo.setValidity(true);
        } catch (ParseException e) {
            logger.error("解析前台传递的时间有误，直接返回参数异常到前台，方法名为：" + methodName + "，时间为startTime=" + startTime + ",endTime=" + endTime);
            datePojo.setValidity(false);
            datePojo.setMsg("校验前台传递时间参数报错");
            return datePojo;
        }
        if (!compareDate(datePojo.getEndTime(), datePojo.getStartTime())) {
            datePojo.setMsg("起始时间大于截止时间");
        }
        return datePojo;
    }

    /**
     * 检测前台传来的时间参数是否合法(时分秒)
     *
     * @param startTime  起始时间
     * @param endTime    截止时间
     * @param methodName 方法名方便日志记录
     */
    public static DatePojo validateDateTime(String startTime, String endTime, String methodName) {
        DatePojo datePojo = new DatePojo();
        Date sTime;
        Date eTime;
        SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            sTime = sdfs.parse(startTime);
            datePojo.setStartTime(sTime);
            eTime = sdfs.parse(endTime);
            datePojo.setEndTime(eTime);
            datePojo.setValidity(true);
        } catch (ParseException e) {
            logger.error("解析前台传递的时间有误，直接返回参数异常到前台，方法名为：" + methodName + "，时间为startTime=" + startTime + ",endTime=" + endTime);
            datePojo.setValidity(false);
            datePojo.setMsg("校验前台传递时间参数报错");
            return datePojo;
        }
        if (!compareDate(datePojo.getEndTime(), datePojo.getStartTime())) {
            datePojo.setMsg("起始时间大于截止时间");
        }
        return datePojo;
    }

    /**
     * 判断截止时间是否为当日
     *
     * @param endTime 截止时间
     */
    private static boolean judgeEndTime(String endTime, SimpleDateFormat sdf) throws ParseException {
        Date endDate = sdf.parse(endTime);
        Calendar enCal = Calendar.getInstance();
        enCal.setTime(endDate);
        Calendar nowCal = Calendar.getInstance();
        boolean isSameYear = nowCal.get(Calendar.YEAR) == enCal.get(Calendar.YEAR);
        boolean isSameMonth = isSameYear && nowCal.get(Calendar.MONTH) == enCal.get(Calendar.MONTH);
        boolean isSameDate = isSameMonth && nowCal.get(Calendar.DAY_OF_MONTH) == enCal.get(Calendar.DAY_OF_MONTH);
        return isSameDate;
    }


    /**
     * 选择时间段查询时
     * 检测前台传来的时间参数是否合法
     *
     * @param startTime  起始时间
     * @param endTime    截止时间
     * @param methodName 方法名方便日志记录
     */
    public static DatePojo ChooseDate(String startTime, String endTime, String methodName) {
        DatePojo datePojo = new DatePojo();
        Date sTime;
        Date eTime;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            sTime = sdf.parse(startTime);
            datePojo.setStartTime(sTime);
            endTime = endTime + ":59:59";
            eTime = sdfs.parse(endTime);
            datePojo.setEndTime(eTime);
            datePojo.setValidity(true);
        } catch (ParseException e) {
            logger.error("解析前台传递的时间有误，直接返回参数异常到前台，方法名为：" + methodName + "，时间为startTime=" + startTime + ",endTime=" + endTime);
            datePojo.setValidity(false);
        }
        return datePojo;
    }

    /**
     * 初始化result
     *
     * @param username 用户名 只有未登录才有用
     * @param request  请求头
     * @param logType  日志类型
     * @param level    严重度
     */
    public static HttpResult initResult(String username, HttpServletRequest request, String logType, int level) {
        HttpResult result = new HttpResult();
        User token = TokenManager.getToken();
        Session session = TokenManager.getSession();
        SessionStatus sessionStatus = (SessionStatus) session.getAttribute(UserSessionManager.SESSION_STATUS);
        Boolean status = sessionStatus.isOnlineStatus();
        if (null == token || !status) {
            //未登录
            result.setUserName(username);
            result.setUserIndex(username);
        } else {
            result.setUserIndex(TokenManager.getToken().getUserIndex());
            result.setUserName(TokenManager.getToken().getLoginName());
        }
        result.setIp(getIpAddr(request));
        result.setLogType(logType);
        result.setLevel(level);
        return result;
    }


    /**
     * @param body          返回主体内容
     * @param code          返回状态码
     * @param message       返回信息
     * @param operate       用户操作
     * @param operateResult 操作结果
     */
    public static HttpResult assignmentResultLog(Object body, int code, String message, String operate, String operateResult, HttpResult tempResult) {
        HttpResult result = new HttpResult();
        result.setBody(body);
        result.setCode(code);
        result.setMessage(message);
        result.setUserIndex(tempResult.getUserIndex());
        result.setUserName(tempResult.getUserName());
        result.setOperate(operate);
        result.setLogType(tempResult.getLogType());
        result.setIp(tempResult.getIp());
        result.setLevel(tempResult.getLevel());
        result.setResult(operateResult);
        return result;
    }

    /**
     * @param body    返回主体内容
     * @param code    返回状态码
     * @param message 返回信息
     */
    public static HttpResult assignmentResult(Object body, int code, String message) {
        HttpResult result = new HttpResult();
        result.setBody(body);
        result.setCode(code);
        result.setMessage(message);
        return result;
    }

    /**
     * 获取当前的日期
     */
    public static String getRightNow() {
        Calendar rightNow = Calendar.getInstance();
        Integer year = rightNow.get(Calendar.YEAR);
        Integer month = rightNow.get(Calendar.MONTH) + 1;
        Integer day = rightNow.get(rightNow.DAY_OF_MONTH);
        return year + "年" + month + "月" + day + "日";
    }

    public static String getNow() {
        DateFormat bf = new SimpleDateFormat("yyyyMMddHHmmss");
        return bf.format(new Date());
    }

    public static String getClientIpAddress(HttpServletRequest request) {
        String ipAddress = request.getHeader("X-Forwarded-For");
        if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
        }
        return isBlank(ipAddress) ? "127.0.0.1" : ipAddress;
    }

    /**
     * 获取当前网络ip
     *
     * @param request 请求
     */
    public static String getIpAddr(HttpServletRequest request) {
//        String ipAddress = request.getHeader("x-forwarded-for");
//        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
//            ipAddress = request.getHeader("Proxy-Client-IP");
//        }
//        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
//            ipAddress = request.getHeader("WL-Proxy-Client-IP");
//        }
//        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
//
//        }
//        //对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
//        if (ipAddress != null && ipAddress.length() > 15) { //"***.***.***.***".length() = 15
//            if (ipAddress.indexOf(",") > 0) {
//                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
//            }
//        }

        String ipAddress = request.getRemoteAddr();
        if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
            //根据网卡取本机配置的IP
            InetAddress inet = null;
            try {
                inet = InetAddress.getLocalHost();
            } catch (UnknownHostException e) {
                logger.error("获取ip地址异常，异常是" + e.getMessage());
            }
            ipAddress = inet.getHostAddress();
        }

        return isBlank(ipAddress) ? "127.0.0.1" : ipAddress;
    }

    /**
     * 判断暂降事件wavename是否为空，以及判断本地是否存在该文件
     */
    public static boolean judgeWaveName(EventDetail eventDetail, String path, NtlmPasswordAuthentication auth) {
        boolean flag = false;
        if (StringUtils.isNotBlank(eventDetail.getWaveName())) {
            //判断文件在不在
            String fileNameTemp = eventDetail.getWaveName() + ".CFG";
            String pathTemp = path + "\\" + fileNameTemp;
            File file = new File(pathTemp);
            // 判断文件是否存在
            if (file.isFile() && file.exists()) {
                flag = true;
            }
        }
        return flag;
    }

    /************************
     * 根据文件名称获取标准字符串
     * @param strCfgName 文件cfg名称
     * @return 返回标准的时间格式
     *************************/
    public static Date GetDateByCfgName(String strCfgName, SimpleDateFormat sdf) {
        Date resultDate = null;//原始时间
        try {
            String[] strOriginalTime = strCfgName.substring(0, strCfgName.lastIndexOf(".")).split("_");

            if (strOriginalTime.length == 4) {
                StringBuilder sbOriginalTime = new StringBuilder();
                //年
                sbOriginalTime.append(strOriginalTime[1].substring(0, 4));
                sbOriginalTime.append("-");
                //月
                sbOriginalTime.append(strOriginalTime[1].substring(4, 6));
                sbOriginalTime.append("-");
                //日
                sbOriginalTime.append(strOriginalTime[1].substring(6, 8));
                sbOriginalTime.append(" ");

                //时
                sbOriginalTime.append(strOriginalTime[2].substring(0, 2));
                sbOriginalTime.append(":");
                //分
                sbOriginalTime.append(strOriginalTime[2].substring(2, 4));
                sbOriginalTime.append(":");
                //秒
                sbOriginalTime.append(strOriginalTime[2].substring(4, 6));
                sbOriginalTime.append(".");

                //毫秒
                sbOriginalTime.append(strOriginalTime[3]);
                //按照格式对时间进行转换
                resultDate = sdf.parse(sbOriginalTime.toString());
            }

        } catch (ParseException e) {
            logger.error(e.getMessage());
        }

        return resultDate;
    }

    /**
     * 统一释放关闭连接
     *
     * @param closeableHttpResponse 响应结果
     */
    public static void releaseResponse(CloseableHttpResponse closeableHttpResponse) {
        if (null != closeableHttpResponse) {
            try {
                closeableHttpResponse.close();
            } catch (IOException e) {
                logger.error("关闭连接出错，异常为：" + e.toString());
            }
        }
    }

    /**
     * 正则表达式字符串
     * 要匹配的字符串
     *
     * @return 如果str 符合 regex的正则表达式格式,返回true, 否则返回 false;
     */
    public static boolean match(String regex, String str) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }

    /**
     * 正则判断密码
     *
     * @param password 密码
     */
    public static boolean patternPassword(String password) {
        return match(PatternRegex.Password_REGEX, password);
    }


    /**
     * 正则判断用户名
     *
     * @param username 用户名
     */
    public static boolean patternUsername(String username) {
        return match(PatternRegex.USERNAME_REGEX, username);
    }

    /**
     *
     */
    public static boolean patterUrl(String path) {
        return match(PatternRegex.URL_REGEX, path);
    }

    /**
     * 正则判断名称
     *
     * @param name 名称
     */
    public static boolean patternName(String name) {
        return match(PatternRegex.NAME_REGEX, name);
    }

    /**
     * 正则判断手机号
     *
     * @param phone 手机号
     */
    public static boolean patternPhone(String phone) {
        return match(PatternRegex.PHONE_REGEX, phone);
    }

    /**
     * 正则判断邮箱
     *
     * @param email 邮箱地址
     */
    public static boolean patternEmail(String email) {
        return match(PatternRegex.Email_REGEX, email);
    }

    /**
     * 正则判断ip地址
     *
     * @param ip ip地址
     */
    public static boolean patternIp(String ip) {
        return match(PatternRegex.ip_REGEX, ip);
    }

    /**
     * 正则判断mac地址
     *
     * @param mac mac地址
     */
    public static boolean patternMac(String mac) {
        return match(PatternRegex.MAC_REGEX, mac);
    }

    /**
     * 正则判断流量套餐
     *
     * @param dataplan
     */
    public static boolean patternDataplan(String dataplan) {
        return match(PatternRegex.DATAPLAN_REGEX, dataplan);
    }

    /**
     * 正则判断角色名
     *
     * @param roleName 角色名
     */
    public static boolean patternRole(String roleName) {
        return match(PatternRegex.ROLE_REGEX, roleName);
    }

    /**
     * 正则判断部门名称
     *
     * @param deptsName 角色名
     */
    public static boolean patternDepts(String deptsName) {
        return match(PatternRegex.DEPTS_REGEX, deptsName);
    }

    /**
     * 正则判断字典名称
     *
     * @param dicName 角色名
     */
    public static boolean patternDic(String dicName) {
        return match(PatternRegex.DIC_REGEX, dicName);
    }

    /**
     * 密码有效期、闲置用户_修改密码、临时账户休眠 1-3月
     *
     * @param passMonth 月份
     */
    public static boolean patternPMonth(String passMonth) {
        return match(PatternRegex.PASSMONTH_REGEX, passMonth);
    }

    /**
     * 密码错误次数1-10次
     *
     * @param passError 错误次数
     */
    public static boolean patternPERROR(String passError) {
        return match(PatternRegex.PASSERROR_REGEX, passError);
    }

    /**
     * 最大并发数 1-99
     *
     * @param maxNum 最大并发
     */
    public static boolean patternMaxNum(String maxNum) {
        return match(PatternRegex.MAXNUM_REGEX, maxNum);
    }

    /**
     * 闲置用户_注销 6-12
     *
     * @param passUpW 时间
     */
    public static boolean patterPUpw(String passUpW) {
        return match(PatternRegex.PASSUPW_REGEX, passUpW);
    }

    /**
     * 临时用户休眠 1-12
     *
     * @param freeMonth
     */
    public static boolean patternFREE(String freeMonth) {
        return match(PatternRegex.FREEMONTH_REGEX, freeMonth);
    }

    /**
     * 审计存储空间 1-2G
     *
     * @param logSize 空间大小
     */
    public static boolean patterLOG(String logSize) {
        return match(PatternRegex.LOGSIZE_REGEX, logSize);
    }

    /**
     * 用户锁定时长 20-60min
     *
     * @param userLock
     */
    public static boolean patternUSERLOCK(String userLock) {
        return match(PatternRegex.USERLOCK_REGEX, userLock);
    }

    /**
     * 正则判断台账名称
     *
     * @param name 名称
     */
    public static boolean patternDevname(String name) {
        return match(PatternRegex.devname_REGEX, name);
    }

    /**
     * 正则判断float
     *
     * @param flo float值
     */
    public static boolean patternFloat(String flo) {
        return match(PatternRegex.float_REGEX, flo);
    }

    /**
     * 正则判断识别码秘钥
     *
     * @param series 识别码秘钥
     */
    public static boolean patternSeries(String series) {
        return match(PatternRegex.series_REGEX, series);
    }

    /**
     * 正则判断分段IP
     *
     * @param sIp 分段ip
     */
    public static boolean patternSIp(String sIp) {
        return match(PatternRegex.sip_REGEX, sIp);
    }

    /**
     * 正则判断端口号
     *
     * @param port 端口号
     */
    public static boolean patternPort(String port) {
        return match(PatternRegex.port_REGEX, port);
    }

    /**
     * 正则判断sim卡号
     *
     * @param sim sim卡号
     */
    public static boolean patternSim(String sim) {
        return match(PatternRegex.ZHENG_REGEX, sim);
    }

    /**
     * 正则判断备注
     *
     * @param remark 备注
     */
    public static boolean patternRemark(String remark) {
        return match(PatternRegex.remark_REGEX, remark);
    }

    /**
     * 正则判断国网平台监测点号
     *
     * @param monitorid 监测点号
     */
    public static boolean patternmonitorid(String monitorid) {
        return match(PatternRegex.monitorid_REGEX, monitorid);
    }

    /**
     * 正则判断变压器名称
     */
    public static boolean patternTrans(String tranName) {
        return match(PatternRegex.TRANSNAME_REGEX, tranName);
    }

    /**
     * 正则判断变压器策略名称
     */
    public static boolean patternTF(String tfName) {
        return match(PatternRegex.TFNAME_REGEX, tfName);
    }

    /**
     * 正则判断字典类型名称
     */
    public static boolean patternTyPe(String typeName) {
        return match(PatternRegex.TYPE_REGEX, typeName);
    }

    /**
     * 正则判断描述10位
     */
    public static boolean patternDes10(String desName) {
        return match(PatternRegex.DES10_REGEX, desName);
    }

    /**
     * 正则判断描述64位
     */
    public static boolean patternDes64(String desName) {
        return match(PatternRegex.DES64_REGEX, desName);
    }

    /**
     * 正则判断描述200位
     */
    public static boolean patternDes200(String desName) {
        return match(PatternRegex.DES200_REGEX, desName);
    }

    /**
     * 正则判断描述500位
     */
    public static boolean patternDes500(String desName) {
        return match(PatternRegex.DES500_REGEX, desName);
    }

    /**
     * 正则判断十六进制颜色
     */
    public static boolean patternColor(String color) {
        return match(PatternRegex.COLOR_REGEX, color);
    }


    /**
     * 获取ssoToken的值
     */
    public static String getSSOToken(HttpServletRequest request) {
        String tokenValue = "";
        //开始判断cookie中ssoToken有没有值
        Cookie[] cookies = request.getCookies();
        if (ArrayUtils.isNotEmpty(cookies)) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equalsIgnoreCase("ssoToken")) {
                    tokenValue = cookie.getValue();
                }
            }
        }
        return tokenValue;
    }


    public static boolean createFile(String destFileName) {
        File file = new File(destFileName);
        if (file.exists()) {
            logger.warn("创建单个文件" + destFileName + "失败，目标文件已存在！");
            return false;
        }
        if (destFileName.endsWith(File.separator)) {
            logger.warn("创建单个文件" + destFileName + "失败，目标文件不能为目录！");
            return false;
        }
        //判断目标文件所在的目录是否存在
        if (!file.getParentFile().exists()) {
            //如果目标文件所在的目录不存在，则创建父目录
            logger.warn("目标文件所在目录不存在，准备创建它！");
            if (!file.getParentFile().mkdirs()) {
                logger.warn("创建目标文件所在目录失败！");
                return false;
            }
        }
        //创建目标文件
        try {
            if (file.createNewFile()) {
                logger.warn("创建单个文件" + destFileName + "成功！");
                return true;
            } else {
                logger.warn("创建单个文件" + destFileName + "失败！");
                return false;
            }
        } catch (IOException e) {
            logger.warn("创建单个文件" + destFileName + "失败！" + e.getMessage());
            return false;
        }
    }



    /**
     * 时间戳转换成日期格式字符串
     *
     * @param seconds 精确到秒的字符串
     * @param format  日期格式
     */
    public static String timeStamp2Date(String seconds, String format) {
        if (isBlank(seconds)) {
            return "";
        }
        if (isBlank(format)) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.valueOf(seconds + "000")));
    }

    /**
     * 时间戳转换成日期格式字符串
     *
     * @param seconds 精确到毫秒的字符串
     * @param format  日期格式
     */
    public static String timeStamp3Date(Long seconds, String format) {
        if (isBlank(format)) {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.valueOf(seconds)));
    }

    /**
     * 根据参数返回float的四舍五入值
     *
     * @param i     保留的位数
     * @param value float原值
     */
    public static Float floatRound(int i, float value) {
        BigDecimal bp = new BigDecimal(value);
        return bp.setScale(i, BigDecimal.ROUND_HALF_UP).floatValue();
    }

    /**
     * 根据参数返回double的四舍五入值
     *
     * @param i     保留的位数
     * @param value double原值
     */
    public static double doubleRound(int i, double value) {
        BigDecimal bp = new BigDecimal(value);
        return bp.setScale(i, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 根据起始时间和截止时间返回yyyy-MM-dd的日期，
     *
     * @param startTime 起始时间
     * @param endTime   截止时间
     */
    public static List<String> getTimes(Date startTime, Date endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<String> result = new ArrayList<>();
        Calendar start = Calendar.getInstance();
        start.setTime(startTime);
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        end.set(end.get(Calendar.YEAR), end.get(Calendar.MONTH), end.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        long interval = end.getTimeInMillis() - start.getTimeInMillis();
        result.add(sdf.format(start.getTime()));
        if (interval > 0) {
            int days = (int) (interval / 86400000);
            for (int i = 0; i < days; i++) {
                start.add(Calendar.DAY_OF_MONTH, 1);
                result.add(sdf.format(start.getTime()));
            }
        }
        return result;
    }


    /**
     * 将当前时间的秒数置为0
     *
     * @param date 时间
     */
    public static Date getSecondsAsZero(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取SM2秘钥对
     */
    public static Map<String, String> getSM2CipHer() throws NoSuchAlgorithmException {
        //秘钥队
        Map<String, String> resutlMap = new HashMap<String, String>();

        //生成密钥对
        ECDomainParameters domainParameters = PubUtils.GetSM2ECDomain();
        ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
        keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
        AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();

        //私钥，16进制格式，自己保存，格式如a2081b5b81fbea0b6b973a3ab6dbbbc65b1164488bf22d8ae2ff0b8260f64853
        BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
        //公钥，16进制格式，发给前端，格式如04813d4d97ad31bd9d18d785f337f683233099d5abed09cb397152d50ac28cc0ba43711960e811d90453db5f5a9518d660858a8d0c57e359a8bf83427760ebcbba
        ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();

        resutlMap.put("privateKey", privatekey.toString(16));
        resutlMap.put("publicKey", Hex.toHexString(ecPoint.getEncoded(false)));
        return resutlMap;
    }

    /**
     * 获取SM2秘钥队证书
     */
    public static ECDomainParameters GetSM2ECDomain() {
        ECDomainParameters domainParameters = null;
        //生成密钥对
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName(String.valueOf("sm2p256v1"));
        domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
        //返回证书
        return domainParameters;
    }


    /**
     * SM2密码有效性，传输完整性验证
     */
    public static String getPasswordSM2Verify(String privateKey, String strPwd) {
        String strResultPwd = null;
        try {
            String password = SM2.decrypt(privateKey, strPwd);
            //数据完整性判断
            String passwordIntegrity = PubUtils.getPasswordIntegrity(password);
            //数据完整性未破坏
            if (passwordIntegrity != null && passwordIntegrity.length() != 0) {
                strResultPwd = passwordIntegrity;
            }
        } catch (Exception e) {
            strResultPwd = null;
            logger.error("解析密码有效性出错，异常为：" + e.toString());
        }
        return strResultPwd;
    }

    /**
     * 验证数据完整性
     *
     * @param strPwd 加密面
     */
    public static String getPasswordIntegrity(String strPwd) {
        String strResultPwd = null;
        String[] tmpPwd = strPwd.split("\\|");//分割解密后的密码
        if (tmpPwd.length == 2) {
            byte[] md = new byte[32];
            byte[] msg1 = tmpPwd[1].getBytes();
            SM3Digest sm3 = new SM3Digest();
            sm3.update(msg1, 0, msg1.length);
            sm3.doFinal(md, 0);
            //前台Sm3加密后的密码是否跟后台密码密码一致
            String tmpstrPwd = new String(Hex.encode(md));
            if (tmpPwd[0].equals(tmpstrPwd)) {
                //假如一致则密码未给破坏
                strResultPwd = tmpPwd[1];
            }
        }
        return strResultPwd;
    }

    /**
     * SM3加密
     *
     * @param strParameter 需要加密参数
     */
    public static String getEncodSM3(String strParameter) {
        String tmpresult;
        try {
            byte[] md = new byte[32];
            byte[] msg1 = strParameter.getBytes();
            SM3Digest sm3 = new SM3Digest();
            sm3.update(msg1, 0, msg1.length);
            sm3.doFinal(md, 0);
            //对传入的参数进行SM3进行加密
            tmpresult = new String(Hex.encode(md));
        } catch (Exception e) {
            tmpresult = null;
            logger.error("对参数" + strParameter + "SM3加密失败，异常为：" + e.toString());
        }
        return tmpresult;
    }

    /**
     * RSA解密密碼
     *
     * @param strPwd 加密面
     */
    public static String getPasswordRSAVerify(RSAPrivateKey privateKey, String strPwd) {
        String strResultPwd = null;
        try {
            String password = RSAUtils.decryptByPrivateKey(strPwd, privateKey);
            //数据完整性判断
            String passwordIntegrity = PubUtils.getPasswordIntegrity(password);
            //数据完整性未破坏
            if (passwordIntegrity != null && passwordIntegrity.length() != 0) {
                strResultPwd = passwordIntegrity;
            }
        } catch (Exception e) {
            strResultPwd = null;
            logger.error("解析密码有效性出错，异常为：" + e.toString());
        }
        return strResultPwd;
    }


    /**
     * 编码
     *
     * @param input
     * @return
     * @throws Exception
     */
    public static String encodeBase64(byte[] input) throws Exception {
        Class clazz = Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
        Method mainMethod = clazz.getMethod("encode", byte[].class);
        ReflectionUtils.makeAccessible(mainMethod);
        Object retObj = mainMethod.invoke(null, new Object[]{input});
        return (String) retObj;
    }

    /**
     * 解码
     *
     * @param input
     * @return
     * @throws Exception
     */
    public static byte[] decodeBase64(String input) throws Exception {
        Class clazz = Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
        Method mainMethod = clazz.getMethod("decode", String.class);
        ReflectionUtils.makeAccessible(mainMethod);
        Object retObj = mainMethod.invoke(null, input);
        return (byte[]) retObj;
    }

    /**
     * 组合app返回实体
     */
    public static ResponseInfoData assignmentAppResponse(int resultCode, int msgCode, String msg) {
        ResponseInfoData responseInfoData = new ResponseInfoData();
        responseInfoData.setResultCode(resultCode);
        responseInfoData.setMsgCode(msgCode);
        responseInfoData.setMsg(msg);
        return responseInfoData;
    }

    /**
     * 组合app返回实体
     */
    public static ResponseData assignmentAppResponse(int resultCode, int msgCode, String msg, Object data) {
        ResponseData responseData = new ResponseData();
        responseData.setResultCode(resultCode);
        responseData.setMsgCode(msgCode);
        responseData.setMsg(msg);
        responseData.setData(data);
        return responseData;
    }

    /**
     * 组合app返回实体
     */
    public static ResponseMsgData assignmentAppResponse(int resultCode, int msgCode, String msg, int unstate, Object data) {
        ResponseMsgData responseData = new ResponseMsgData();
        responseData.setResultCode(resultCode);
        responseData.setMsgCode(msgCode);
        responseData.setMsg(msg);
        responseData.setUnstate(unstate);
        responseData.setData(data);
        return responseData;
    }

    /**
     * 组合app返回实体
     */
    public static DataIntegrMsgData assignmentAppDataIntgrResponse(int resultCode, int msgCode, String msg, Date timeStart, Date timeEnd, Float integrity_tj, Object data) {
        DataIntegrMsgData responseData = new DataIntegrMsgData();
        responseData.setResultCode(resultCode);
        responseData.setMsgCode(msgCode);
        responseData.setMsg(msg);
        responseData.setTimeStart(timeStart);
        responseData.setTimeEnd(timeEnd);
        responseData.setIntegrityz(integrity_tj);
        responseData.setData(data);
        return responseData;
    }

    /**
     * 组合app返回实体
     */
    public static StaticMsgData assignmentAppStaticResponse(int resultCode, int msgCode, String msg, Date timeStart, Date timeEnd, Float onlineRate_tj, int comError, Object data) {
        StaticMsgData responseData = new StaticMsgData();
        responseData.setResultCode(resultCode);
        responseData.setMsgCode(msgCode);
        responseData.setMsg(msg);
        responseData.setTimeStart(timeStart);
        responseData.setTimeEnd(timeEnd);
        responseData.setOnlineRatez(onlineRate_tj);
        responseData.setComError(comError);
        responseData.setData(data);
        return responseData;
    }

    /**
     * 组合app返回实体
     */
    public static ResponseEigMsgData assignmentAppEigResponse(int resultCode, int msgCode, String msg, int backNumber, String sagReason, Object data) {
        ResponseEigMsgData responseData = new ResponseEigMsgData();
        responseData.setResultCode(resultCode);
        responseData.setMsgCode(msgCode);
        responseData.setMsg(msg);
        responseData.setBackNumber(backNumber);
        responseData.setSagReason(sagReason);
        responseData.setData(data);
        return responseData;
    }

    public static boolean patternPasswordPhone(String password) {
        return match(PatternRegex.Password_PHONE_REGEX, password);
    }

    /**
     * 计算该日期距离今天多少天，向下取值
     */
    public static long getDays(Date targetDate) {
        Date now = new Date();
        long targetTime = targetDate.getTime();
        long nowTime = now.getTime();
        return (nowTime - targetTime) / 86400000;
    }


    /**
     * 采用密码学的随机数生成规则生成随机int值
     *
     * @Param scope随机数范围
     */
    public static int getRandomInt(int scope) {
        int result = 0;
        SecureRandom random;
        try {
            random = SecureRandom.getInstance("SHA1PRNG");
            result = random.nextInt(scope);
        } catch (NoSuchAlgorithmException e) {
            logger.error("生成随机数失败，异常为：" + e.toString());
        }
        return result;
    }

    public static String getCurrentYAndM() {
        Calendar cal = Calendar.getInstance();
        String year = String.valueOf(cal.get(Calendar.YEAR));
        String month = String.valueOf(cal.get(Calendar.MONTH) + 1);
        if (parseInt(month) < 10) {
            month = "0" + month;
        }
        return year + "-" + month;
    }

    /**
     * 安全关闭socket
     *
     * @param s
     */
    public static void safeClose(Socket s) {
        if (s != null && !s.isClosed()) {
            try {
                s.close();
            } catch (IOException e) {
                logger.error("安全关闭socket失败，异常为：" + e.toString());
            }
        }
    }

    /**
     * 安全关闭InputStream
     *
     * @param s
     */
    public static void safeClose(InputStream s, String strError) {
        if (s != null) {
            try {
                s.close();
            } catch (IOException e) {
                logger.error(strError + e.toString());
            }
        }
    }

    /**
     * 安全关闭FileInputStream
     *
     * @param s
     */
    public static void safeClose(FileInputStream s, String strError) {
        if (s != null) {
            try {
                s.close();
            } catch (IOException e) {
                logger.error(strError + e.toString());
            }
        }
    }

    /**
     * 安全关闭OutputStream
     *
     * @param s
     */
    public static void safeClose(OutputStream s, String strError) {
        if (s != null) {
            try {
                s.close();
            } catch (IOException e) {
                logger.error(strError + e.toString());
            }
        }
    }

    /**
     * 安全关闭RandomAccessFile
     *
     * @param s
     */
    public static void safeClose(RandomAccessFile s, String strError) {
        if (s != null) {
            try {
                s.close();
            } catch (IOException e) {
                logger.error(strError + e.toString());
            }
        }
    }

    /**
     * 读取配置文件
     *
     * @param cl                类名字
     * @param strPropertiesName 配置文件名称
     */
    public static Properties readProperties(ClassLoader cl, String strPropertiesName) {
        Properties pros = new Properties();
        InputStream in = null;
        try {
            in = cl.getResourceAsStream(strPropertiesName);
            pros.load(in);
        } catch (Exception e) {
            logger.error("读取配置文件失败失败：" + e.getMessage());
        } finally {
            if (in != null) {
                PubUtils.safeClose(in, "安全关闭读取配置文件失败，异常为：");
            }
        }
        return pros;
    }


    public static void downloadChrome(HttpServletResponse response, List<ManageList> manageLists) {

        if (!manageLists.isEmpty()) {
            File directory = new File(manageLists.get(0).getRes_Url());//取路径
            // 下载本地文件
            String fileName = directory.getName();
            // 读到流中
            // 设置输出的格式
            FileInputStream inStream = null;
            try {
                inStream = new FileInputStream(directory);
                response.reset();
                response.setContentType("bin");
                // 循环取出流中的数据
                byte[] b = new byte[100];
                int len;
                response.addHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("gb2312"), "ISO8859-1"));
                while ((len = inStream.read(b)) > 0)
                    response.getOutputStream().write(b, 0, len);
                inStream.close();
            } catch (Exception e) {
                logger.error("获取流中的数据发生异常，异常是" + e.getMessage());
                return;
            }
        }
    }

    public static HttpResult foundChrome(List<ManageList> manageLists) {
        HttpResult result = new HttpResult();
        if (!manageLists.isEmpty()) {
            File directory = new File(manageLists.get(0).getRes_Url());
            // 下载本地文件
            String fileName = directory.getName(); // 文件的默认保存名
            FileInputStream inStream = null;
            try {
                inStream = new FileInputStream(directory);
                result.setCode(200);
                result.setMessage("获取到源文件成功");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                result.setCode(500);
                result.setMessage("该资源本地未找到");
            }
        } else {
            result.setCode(500);
            result.setMessage("该资源本地未找到");
        }
        return result;
    }

    public static String getConfirmIndentity() {
        String password = "";
        try {
            Calendar now = Calendar.getInstance();
            int year = now.get(Calendar.YEAR);
            password += year;
            int month = (now.get(Calendar.MONTH) + 1);
            if (month < 10) {
                password += "0" + month;
            } else {
                password += month;
            }
            int day = now.get(Calendar.DAY_OF_MONTH);
            if (day < 10) {
                password += "0" + day;
            } else {
                password += day;
            }
            int hours = now.get(Calendar.HOUR_OF_DAY);
            if (hours < 10) {
                password += "0" + hours;
            } else {
                password += hours;
            }
        } catch (Exception e) {
            password = "";
        }
        return password;
    }


    /**
     * 字符串非空判断增强
     * 常规的非空，直接采用StringUtils的isEmpty即可
     */
    public static boolean isBlank(String args) {
        if(StringUtils.isEmpty(args) || "null".equalsIgnoreCase(args)){
            return Boolean.TRUE;
        }
        return false;
    }
}
