Java 随机字符串类 工具类

发布时间 2023-12-20 23:59:58作者: tothk

Java 随机字符串工具类

随机生成字符串的工具类,在I7 10代 CPU下,大概每秒300不重复,没有使用第三方jar

package com.chohn;

import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.time.Instant;
import java.util.Enumeration;
import java.util.concurrent.ThreadLocalRandom;

public class RandomString {
    private static final Integer DEFAULT_LENGTH = 40;

    public static String getRandomString() {
        return getRandomString(DEFAULT_LENGTH);
    }

    public static String getRandomString(Integer str_length) {
        if (str_length <= 0) {
            return "";
        }
        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder result = new StringBuilder();
        // 获取当前时间
        long epochMilli = Instant.now().toEpochMilli();
        long nano = Instant.now().getNano();
        stringBuilder.append(epochMilli);
        stringBuilder.append(nano);

        // 获取系统ip地址
        String address = getLocalHostExactAddress();
        stringBuilder.append(address);

        // 获取内存使用情况
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
        // 堆内存使用情况
        MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage();
        // 已使用的内存
        Long usedMemorySize = memoryUsage.getUsed();
        long memoryUsageCommitted = memoryUsage.getCommitted();
        // 堆外内存使用情况
        MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
        long used = nonHeapMemoryUsage.getUsed();
        stringBuilder.append(usedMemorySize);
        stringBuilder.append(memoryUsageCommitted);
        stringBuilder.append(used);

        // 获取一个随机数
        int randomNum = ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);
        
        result.append(Hash.getSHA1(stringBuilder.toString()));

        while (result.length() < str_length) {
            result.append(Hash.getSHA1(result.toString()));
        }
        return result.substring(0, str_length);
    }

    private static String getLocalHostExactAddress() {
        try {
            InetAddress candidateAddress = null;
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface iface = networkInterfaces.nextElement();
                // 该网卡接口下的ip会有多个,也需要一个个的遍历,找到自己所需要的
                for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {
                    InetAddress inetAddr = inetAddrs.nextElement();
                    // 排除loopback回环类型地址(不管是IPv4还是IPv6 只要是回环地址都会返回true)
                    if (!inetAddr.isLoopbackAddress()) {
                        if (inetAddr.isSiteLocalAddress()) {
                            // 如果是site-local地址,就是它了 就是我们要找的
                            // ~~~~~~~~~~~~~绝大部分情况下都会在此处返回你的ip地址值~~~~~~~~~~~~~
                            return inetAddr.toString();
                        }
                        // 若不是site-local地址 那就记录下该地址当作候选
                        if (candidateAddress == null) {
                            candidateAddress = inetAddr;
                        }
                    }
                }
            }
            // 如果出去loopback回环地之外无其它地址了,那就回退到原始方案吧
            if (candidateAddress == null) {
                return InetAddress.getLocalHost().toString();
            } else {
                return candidateAddress.toString();
            }
        } catch (SocketException | UnknownHostException e) {
            e.printStackTrace();
        }
        return "127.0.0.1";
    }
}

Hash工具类

package com.chohn;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Hash {

    private static final String SHA_1 = "SHA-1";
    private static final String SHA_256 = "SHA-256";
    private static final String SHA_512 = "SHA-512";

    public static final Boolean DEFAULT_UPPERCASE = false;

    private static final char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    public static String getSHA1(String painText) {
        return getSha(painText, SHA_1, DEFAULT_UPPERCASE);
    }

    public static String getSHA1(String painText, boolean uppercase) {
        return getSha(painText, SHA_1, uppercase);
    }

    public static String getSHA256(String painText) {
        return getSha(painText, SHA_256, DEFAULT_UPPERCASE);
    }

    public static String getSHA256(String painText, boolean uppercase) {
        return getSha(painText, SHA_256, uppercase);
    }

    public static String getSHA512(String painText) {
        return getSha(painText, SHA_512, DEFAULT_UPPERCASE);
    }

    public static String getSHA512(String painText, boolean uppercase) {
        return getSha(painText, SHA_512, uppercase);
    }

    /**
     * 利用Java原生摘要实现SHA加密(支持大小写,默认小写)
     *
     * @param plainText 要加密的数据
     * @param algorithm 要使用的算法(SHA-1,SHA-2224,SHA-256,SHA-384,SHA-512)
     * @param uppercase 是否转为大写
     * @return
     */
    private static String getSha(String plainText, String algorithm, boolean uppercase) {
        //输入的字符串转换成字节数组
        byte[] bytes = plainText.getBytes(StandardCharsets.UTF_8);
        MessageDigest messageDigest;
        try {
            //获得SHA转换器
            messageDigest = MessageDigest.getInstance(algorithm);
            //bytes是输入字符串转换得到的字节数组
            messageDigest.update(bytes);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA签名过程中出现错误,算法异常");
        }
        //转换并返回结果,也是字节数组,包含16个元素
        byte[] digest = messageDigest.digest();
        //字符数组转换成字符串返回
        String result = byteArrayToHexString(digest);
        //转换大写
        return uppercase ? result.toUpperCase() : result;
    }

    /**
     * 将字节数组转为16进制字符串
     *
     * @param bytes 要转换的字节数组
     * @return
     */
    private static String byteArrayToHexString(byte[] bytes) {
        StringBuilder builder = new StringBuilder();
        for (byte b : bytes) {
            //java.lang.Integer.toHexString() 方法的参数是int(32位)类型,
            //如果输入一个byte(8位)类型的数字,这个方法会把这个数字的高24为也看作有效位,就会出现错误
            //如果使用& 0XFF操作,可以把高24位置0以避免这样错误
            String temp = Integer.toHexString(b & 0xFF);
            if (temp.length() == 1) {
                //1得到一位的进行补0操作
                builder.append("0");
            }
            builder.append(temp);
        }
        return builder.toString();
    }

}

Hash工具类来源:https://blog.csdn.net/Alian_1223/article/details/117443522

有一些小修改

获取ip地址方法来源:https://cloud.tencent.com/developer/article/1610919

最后编辑时间:2023年12月20日23:48:05