Java 随机字符串类 工具类
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