首页 > 技术文章 > Java 工具类—自定义(File/HTTP/IP/Date/RSA/AES)

ruhuanxingyun 2020-07-07 23:18 原文

1. 文件操作

package com.ruhuanxingyun.javabasic.util;

import org.springframework.web.multipart.MultipartFile;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.util.Arrays;

/**
 * @description: 文件工具类
 * @author: ruphie
 * @date: Create in 2020/7/7 23:07
 * @company: ruhuanxingyun
 */
public class FileUtils {

    private static final int SPLIT_SIZE = 10 * 1024 * 1024;

    /**
     * 获取文件MD5值
     *
     * @param file 文件
     * @return MD5
     */
    public static String getFileMd5(MultipartFile file) {
        try {
            byte[] bytes = file.getBytes();
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] digest = messageDigest.digest(bytes);

            return new BigInteger(1, digest).toString(16);
        } catch (Exception e) {
            e.printStackTrace();

            return null;
        }
    }

    /**
     * 文件字节分割
     *
     * @param bytes 字节
     * @return 字节数组
     */
    public static byte[][] splitBytes(byte[] bytes) {
        int bytesLen = bytes.length;
        int arrayLen = (int) Math.ceil(bytesLen / SPLIT_SIZE);
        byte[][] bytesArr = new byte[arrayLen][];
        int from, to;
        for (int i = 0; i < arrayLen; i++) {
            from = i * SPLIT_SIZE;
            to = from + SPLIT_SIZE;
            if (to > bytesLen) {
                to = bytesLen;
            }
            bytesArr[i] = Arrays.copyOfRange(bytes, from, to);
        }

        return bytesArr;
    }

    /**
     * 转换字节单位
     *
     * @param fileSize 文件大小
     * @return 可阅读的大小
     */
    public static String convertByteUnit(Long fileSize) {
        if (fileSize == null || fileSize == 0) {
            return "0B";
        }

        // Long类型无法存储TB单位的,其中GB等注意带上L
        final String[] units = new String[]{"B", "KB", "MB", "GB"};
        int digitGroups = (int) (Math.log10(fileSize) / Math.log10(1024));
        DecimalFormat decimalFormat = new DecimalFormat("#.##");

        return decimalFormat.format(fileSize / Math.pow(1024, digitGroups)) + units[digitGroups];
    }

}
View Code

2. HTTP请求

package com.ruhuanxingyun.javabasic.util;

import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * @description: HTTP请求工具类
 * @author: ruphie
 * @date: Create in 2020/7/8 22:21
 * @company: ruhuanxingyun
 */
public class HttpUtils {

    /**
     * 覆盖java默认的证书验证
     */
    private static final TrustManager[] TRUST_ALL_CERTS = new TrustManager[]{
            new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

                }

                @Override
                public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            }
    };

    /**
     * 设置不验证主机
     */
    private static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
        @Override
        public boolean verify(String s, SSLSession sslSession) {
            return true;
        }
    };

    /**
     * 发送GET请求
     *
     * @param accessUrl         访问url(含参数)
     * @param ignoreCertificate 是否忽略证书认证
     * @param token             请求token
     * @return 请求数据
     */
    public static String sendGet(String accessUrl, boolean ignoreCertificate, String token) {
        HttpURLConnection connection = null;
        InputStream is = null;
        BufferedReader br = null;
        try {
            URL url = new URL(accessUrl);
            connection = (HttpURLConnection) url.openConnection();
            // 是否忽略证书
            if (ignoreCertificate) {
                HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
                trustAllHosts(httpsConnection);
                httpsConnection.setHostnameVerifier(DO_NOT_VERIFY);
            }
            connection.setRequestMethod("GET");
            connection.setRequestProperty("User-Agent", "RuhuanxingyunBrowser/project");
            connection.setRequestProperty("Authorization", String.format("Bearer %s", token));
            connection.connect();

            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                is = connection.getInputStream();
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                StringBuffer sb = new StringBuffer();
                String temp;
                while ((temp = br.readLine()) != null) {
                    sb.append(temp);
                }

                return sb.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            // 关闭远程连接
            if (connection != null) {
                connection.disconnect();
            }
        }

        return null;
    }

    /**
     * 信任所有
     *
     * @param connection https连接
     */
    private static void trustAllHosts(HttpsURLConnection connection) {
        try {
            SSLContext context = SSLContext.getInstance("SSL");
            context.init(null, TRUST_ALL_CERTS, new SecureRandom());
            connection.setSSLSocketFactory(context.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
View Code

3. IP地址

package com.ruhuanxingyun.javabasic.util;

import cn.hutool.core.util.StrUtil;
import sun.net.util.IPAddressUtil;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @description: IP地址工具
 * @author: ruphie
 * @date: Create in 2020/8/30 17:44
 * @company: ruhuanxingyun
 */
public class IPUtils {

    public static final Pattern REGEX_IP = Pattern.compile("^(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}$");

    /**
     * 获取IP地址
     *
     * @param request 请求对象
     * @return IP
     */
    public static String getIpAddress(HttpServletRequest request) {
        // 获取客户端IP地址,考虑反向代理的问题
        String ip = request.getHeader("x-forwarded-for");

        if (StrUtil.isBlank(ip) || StrUtil.equalsIgnoreCase("unknown", ip)) {
            ip = request.getHeader("X-Real-IP");
        }

        if (StrUtil.isBlank(ip) || StrUtil.equalsIgnoreCase("unknown", ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }

        if (StrUtil.isBlank(ip) || StrUtil.equalsIgnoreCase("unknown", ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if (StrUtil.isBlank(ip) || StrUtil.equalsIgnoreCase("unknown", ip)) {
            ip = request.getRemoteAddr();
            if (StrUtil.equals("127.0.0.1", ip) || StrUtil.equals("0:0:0:0:0:0:0:1", ip)) {
                try {
                    InetAddress inetAddress = InetAddress.getLocalHost();
                    ip = inetAddress.getHostAddress();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
            }
        }

        if (StrUtil.isNotBlank(ip) && ip.length() > 15) {
            ip = ip.substring(0, ip.indexOf(","));
        }

        return ip;
    }

    /**
     * 判断IP是否是内网
     * 内网IP网段:
     * 10.0.0.0-10.255.255.255
     * 172.16.0.0-172.31.255.255
     * 192.168.0.0-192.168.255.255
     *
     * @param ip IP
     * @return 真否
     */
    public static boolean isInternalNet1(String ip) {
        if (StrUtil.equals("127.0.0.1", ip) || StrUtil.equals("localhost", ip) || StrUtil.equals("0.0.0.0", ip) || StrUtil.equals("255.255.255.255", ip)) {
            return true;
        }

        String reg = "^(192\\.168|172\\.(1[6-9]|2\\d|3[0,1]))(\\.(2[0-4]\\d|25[0-5]|[0,1]?\\d?\\d)){2}$|^10(\\.([2][0-4]\\d|25[0-5]|[0,1]?\\d?\\d)){3}$";
        Pattern p = Pattern.compile(reg);
        Matcher matcher = p.matcher(ip);

        return matcher.find();
    }

    /**
     * 判断IP是否是内网
     *
     * @param ip IP
     * @return 真否
     */
    public static boolean isInternalNet2(String ip) {
        if (StrUtil.equals("127.0.0.1", ip) || StrUtil.equals("localhost", ip) || StrUtil.equals("0.0.0.0", ip) || StrUtil.equals("255.255.255.255", ip)) {
            return true;
        }

        byte[] addr = IPAddressUtil.textToNumericFormatV4(ip);
        final byte b0 = addr[0];
        final byte b1 = addr[1];
        //10.x.x.x/8
        final byte SECTION_1 = 0x0A;
        //172.16.x.x/12
        final byte SECTION_2 = (byte) 0xAC;
        final byte SECTION_3 = (byte) 0x10;
        final byte SECTION_4 = (byte) 0x1F;
        //192.168.x.x/16
        final byte SECTION_5 = (byte) 0xC0;
        final byte SECTION_6 = (byte) 0xA8;
        switch (b0) {
            case SECTION_1:
                return true;
            case SECTION_2:
                if (b1 >= SECTION_3 && b1 <= SECTION_4) {
                    return true;
                }
            case SECTION_5:
                switch (b1) {
                    case SECTION_6:
                        return true;
                    default:
                        return false;
                }
            default:
                return false;
        }
    }

    /**
     * 校验IP是否合法
     *
     * @param ip IP地址
     * @return 合法与否
     */
    public static boolean checkIp(String ip) {
        return REGEX_IP.matcher(ip).matches();
    }

    /**
     * 判断用户ip是否在指定IP段范围内
     *
     * @param ip      目标IP
     * @param beginIp 起始IP
     * @param endIp   终止IP
     * @return 真否
     */
    public static boolean isInnerIp(String ip, String beginIp, String endIp) {
        long ipNum = getIpNum(ip);
        long beginIpNum = getIpNum(beginIp);
        long endIpNum = getIpNum(endIp);

        return ipNum >= beginIpNum && ipNum <= endIpNum;
    }

    /**
     * 获取IP数
     *
     * @param ipAddress IP地址
     * @return IP数
     */
    private static long getIpNum(String ipAddress) {
        String[] ipArr = ipAddress.split("\\.");
        long a = Integer.parseInt(ipArr[0]);
        long b = Integer.parseInt(ipArr[1]);
        long c = Integer.parseInt(ipArr[2]);
        long d = Integer.parseInt(ipArr[3]);

        return a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
    }

}
View Code

4. 时间转换

package com.ruhuanxingyun.javabasic.util;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;

/**
 * @description: 日期时间工具类
 * @author: ruphie
 * @date: Create in 2020/8/11 10:09
 * @company: ruhuanxingyun
 */
public class DateUtils {

    /**
     * 获取上个月的第一天日期
     *
     * @param pattern 日期格式:如yyyy-MM-dd
     * @return 日期字符串
     */
    public static String getFirstDayOfLastMonth(String pattern) {
        return LocalDateTime.now()
            .minusMonths(1)
            .with(TemporalAdjusters.firstDayOfMonth())
            .format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 获取上个月的最后一天日期
     *
     * @param pattern 日期格式:如yyyy-MM-dd
     * @return 日期字符串
     */
    public static String getLastDayOfLastMonth(String pattern) {
        return LocalDateTime.now()
            .minusMonths(1)
            .with(TemporalAdjusters.lastDayOfMonth())
            .format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 获取当月的第一天日期
     *
     * @param pattern 日期格式:如yyyy-MM-dd
     * @return 日期字符串
     */
    public static String getFirstDayOfMonth(String pattern) {
        return LocalDateTime.now()
            .with(TemporalAdjusters.firstDayOfMonth())
            .format(DateTimeFormatter.ofPattern(pattern));
    }

}
View Code

 5. RSA加密

package com.ruhuanxingyun.javabasic.util;


import cn.hutool.core.util.StrUtil;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: RSA加解密工具
 * @author: ruphie
 * @date: Create in 2020/7/30 22:21
 * @company: ruhuanxingyun
 */
public class RSAUtils {

    /**
     * 加密算法RSA
     */
    private static final String KEY_ALGORITHM = "RSA";

    /**
     * key大小
     */
    private static final int KEY_SIZE = 2048;

    /**
     * 公钥key
     */
    private static final String PUBLIC_KEY = "publicKey";

    /**
     * 私钥key
     */
    private static final String PRIVATE_KEY = "privateKey";


    /**
     * 随机生成秘钥对
     *
     * @return 秘钥对
     * @throws NoSuchAlgorithmException 异常
     */
    public static Map<String, String> generateKey() throws NoSuchAlgorithmException {
        // 密钥对生成器
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        // 初始化
        keyPairGenerator.initialize(KEY_SIZE);
        // 生成一个秘钥对
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        // 公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        // 私钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        Map<String, String> map = new HashMap<>(3);
        map.put(PUBLIC_KEY, encryptByBase64(publicKey.getEncoded()));
        map.put(PRIVATE_KEY, encryptByBase64(privateKey.getEncoded()));

        return map;
    }

    /**
     * 通过RSA公钥加密
     *
     * @param content   需加密内容
     * @param publicKey 公钥
     * @return 密文内容
     * @throws Exception 异常
     */
    public static String encryptByPublicKey(String content, String publicKey) throws Exception {
        // Base64解密的公钥
        byte[] keyBytes = decryptByBase64(publicKey);
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyFactory.generatePublic(x509EncodedKeySpec);

        // RSA加密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey);
        byte[] contentBytes = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));

        return encryptByBase64(contentBytes);
    }

    /**
     * 通过RSA私钥解密
     *
     * @param content    被解密内容
     * @param privateKey 私钥
     * @return 明文内容
     * @throws Exception 异常
     */
    public static String decryptByPrivateKey(String content, String privateKey) throws Exception {
        // Base64解密的私钥
        byte[] keyBytes = decryptByBase64(privateKey);
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        // RSA解密
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey);
        byte[] contentBytes = decryptByBase64(content);
        byte[] bytes = cipher.doFinal(contentBytes);

        return new String(bytes, StandardCharsets.UTF_8);
    }

    /**
     * 通过Base64加密
     *
     * @param content 需加密内容
     * @return 密文内容
     */
    private static String encryptByBase64(byte[] content) {
        return Base64.getEncoder().encodeToString(content);
    }

    /**
     * 通过Base64解密
     *
     * @param content 被解密内容
     * @return 明文内容
     */
    private static byte[] decryptByBase64(String content) {
        return Base64.getDecoder().decode(content);
    }


    public static void main(String[] args) throws Exception {
        String content = "ruphie@5379";
        Map<String, String> map = RSAUtils.generateKey();
        String publicKey = map.get(PUBLIC_KEY);
        String privateKey = map.get(PRIVATE_KEY);
        String ciphertext = encryptByPublicKey(content, publicKey);
        String plaintext = decryptByPrivateKey(ciphertext, privateKey);

        System.out.println("公钥为:" + publicKey);
        System.out.println("私钥为:" + privateKey);
        System.out.println("加密后密文为:" + ciphertext);
        System.out.println("解密后明文为:" + plaintext);
        System.out.println("加密前明文与解密后明文对比为:" + StrUtil.equals(content, plaintext));
    }

}
View Code

6. AES加密

package com.ruhuanxingyun.javabasic.util;

import cn.hutool.core.util.StrUtil;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * @description: AES加解密工具
 * @author: ruphie
 * @date: Create in 2020/7/29 22:21
 * @company: ruhuanxingyun
 */
public class AESUtils {

    /**
     * 加密算法AES
     */
    private static final String KEY_ALGORITHM = "AES";

    /**
     * key大小
     */
    private static final int KEY_SIZE = 128;

    /**
     * CBC工作模式
     */
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";

    /**
     * 随机生成秘钥
     *
     * @return 秘钥
     * @throws NoSuchAlgorithmException 异常
     */
    public static String generateKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
        keyGenerator.init(KEY_SIZE);
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] keyBytes = secretKey.getEncoded();

        return encryptByBase64(keyBytes);
    }

    /**
     * 初始化向量
     *
     * @return 向量字节
     */
    public static byte[] generateIv() {
        byte[] randomBytes = new byte[16];
        SecureRandom sr = new SecureRandom();
        sr.nextBytes(randomBytes);

        return randomBytes;
    }

    /**
     * 通过AES秘钥加密
     *
     * @param content 需加密内容
     * @param key     秘钥
     * @param ivBytes 向量
     * @return 密文内容
     * @throws Exception 异常
     */
    public static String encryptByKey(String content, String key, byte[] ivBytes) throws Exception {
        // Base64解密的秘钥
        byte[] keyBytes = decryptByBase64(key);
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, KEY_ALGORITHM);

        // AES加密
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] contentBytes = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));

        return encryptByBase64(contentBytes);
    }

    /**
     * 通过AES秘钥解密
     *
     * @param content 被解密内容
     * @param key     秘钥
     * @param ivBytes 向量
     * @return 明文内容
     * @throws Exception 异常
     */
    public static String decryptByKey(String content, String key, byte[] ivBytes) throws Exception {
        // Base64解密的秘钥
        byte[] keyBytes = decryptByBase64(key);
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, KEY_ALGORITHM);

        // AES解密
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        byte[] contentBytes = decryptByBase64(content);
        byte[] bytes = cipher.doFinal(contentBytes);

        return new String(bytes, StandardCharsets.UTF_8);
    }

    /**
     * 通过Base64加密
     *
     * @param content 需加密内容
     * @return 密文内容
     */
    private static String encryptByBase64(byte[] content) {
        return Base64.getEncoder().encodeToString(content);
    }

    /**
     * 通过Base64解密
     *
     * @param content 被解密内容
     * @return 明文内容
     */
    private static byte[] decryptByBase64(String content) {
        return Base64.getDecoder().decode(content);
    }


    public static void main(String[] args) throws Exception {
        String content = "ruphie@5379";
        String key = AESUtils.generateKey();
        byte[] ivBytes = AESUtils.generateIv();
        String ciphertext = encryptByKey(content, key, ivBytes);
        String plaintext = decryptByKey(ciphertext, key, ivBytes);

        System.out.println("秘钥为:" + key);
        System.out.println("加密后密文为:" + ciphertext);
        System.out.println("解密后明文为:" + plaintext);
        System.out.println("加密前明文与解密后明文对比为:" + StrUtil.equals(content, plaintext));
    }

}
View Code

 

推荐阅读