13 Commits

Author SHA1 Message Date
a2bfbf1005 添加功能 ColorPrintlnPlus/仿照Minecraft类型的文本终端打印 2026-08-08 04:08:18 +08:00
31024f33c5 修复一些已知的BUG 2026-08-06 03:40:16 +08:00
8ce618e03d 修改 README 2026-08-06 03:32:37 +08:00
b2e94b3b86 修改 README 2026-08-06 03:25:45 +08:00
720ccf1952 Add NOTICE 2026-08-06 03:07:12 +08:00
ba1cbc9674 添加 HWID相关功能 2026-08-05 09:40:10 +08:00
949030d606 添加 随机数生成 2026-08-05 06:45:56 +08:00
350f59bfe2 添加 使用示例 2026-08-03 18:03:25 +08:00
907bde792a README 2026-08-03 17:52:21 +08:00
2ff9313a2a README 2026-08-03 17:51:24 +08:00
7420b84f5f 测试 枚举颜色 2026-08-03 17:25:40 +08:00
4980f0d1f6 修复 echo十六进制彩色打印 2026-08-03 17:09:41 +08:00
c1d105939b Update README 2026-08-03 16:43:42 +08:00
16 changed files with 1344 additions and 22 deletions

2
.gitignore vendored
View File

@@ -38,6 +38,8 @@ build/
### Mac OS ###
.DS_Store
### Other ###
/target
/.idea
/.mvn
/build_release

4
NOTICE Normal file
View File

@@ -0,0 +1,4 @@
gnu_java_utils_library
Copyright 2026 gtb520
本作品基于[gnu_java_utils_library]https://git.opensource-studio.info/database-mysql/gnu_java_utils_library.git构建遵循Apache License 2.0许可协议。

View File

@@ -1,6 +1,6 @@
# GNU Java Utils Library
一个轻量级 Java 工具库,提供常用的压缩/解压与终端彩色输出功能。
一个轻量级 Java 工具库,提供常用的压缩/解压与终端彩色输出功能
## 技术栈
@@ -28,7 +28,7 @@ src/main/java/top/gtb520/java/gnu/java/utils/library/
支持 **Tar.Gz****Zip** 两种压缩格式的压缩与解压操作,支持单文件和整个目录的递归处理。
| 方法 | 说明 | 参数 |
|------|------|------|
|------------------------------------|---------------------|------------------------------|
| `compress.MakeTarGz(source, dest)` | 将文件或目录压缩为 `.tar.gz` | `source` 源路径,`dest` 压缩包输出路径 |
| `compress.UnTarGz(source, dest)` | 解压 `.tar.gz` 到指定目录 | `source` 压缩包路径,`dest` 解压目标目录 |
| `compress.MakeZip(source, dest)` | 将文件或目录压缩为 `.zip` | `source` 源路径,`dest` 压缩包输出路径 |
@@ -66,14 +66,14 @@ main.compress.TarGz(source, dest);
基于 ANSI 转义序列,在终端中输出彩色文本。
| 方法 | 说明 | 参数 |
|------|------|------|
|-------------------------------------------|------------------|-------------------------------------|
| `echo.ColorPrintln(message, color)` | 使用预定义颜色打印 | `message` 文本内容,`color` 颜色枚举 |
| `echo.ColorHexPrintln(message, hexColor)` | 使用自定义 ANSI 颜色码打印 | `message` 文本内容,`hexColor` ANSI 颜色代码 |
**支持的颜色枚举 (`ColorNameEnum`)**
| 枚举值 | 颜色 |
|--------|------|
|----------|----|
| `RED` | 红色 |
| `GREEN` | 绿色 |
| `YELLOW` | 黄色 |
@@ -105,11 +105,96 @@ main.echo.Println("警告信息", ColorNameEnum.YELLOW);
main.echo.ColorHexPrintln("自定义颜色", "31");
```
### 3. 随机生成器 (`random`)
随机生成器提供生成随机字符串、数字、UUID 等功能。
| 方法 | 说明 | 参数 |
|-------------------------------------------------------------|--------------|-----------------------------------|
| `processing.random.defaults.random(start_scope, end_scope)` | 根据输入的范围生成随机数 | `start_scope` 起始数,`end_scope` 结束数 |
| `processing.random.defaults.randomString(int length)` | 生成指定长度的随机字符串 | `length` 字符串长度 |
**使用示例:**
```java
package top.gtb520.java.gnu.java.utils.library.utils.processing.random;
defaults.random(1, 100);
defaults.randomString(10);
```
### 4. HWID生成
HWID生成器提供生成硬件ID的功能
| 方法 | 说明 | 参数 |
|------------------------------------------|--------|----|
| `processing.hwid.getHWID.generateHWID()` | 生成HWID | |
**使用示例**
```java
import top.gtb520.java.gnu.java.utils.library.utils.processing.hwid.getHWID;
String Hwid_Str;
Hwid_Str = getHWID.generateHWID();
System.out.println("HWID: " + Hwid_Str);
System.out.println("HWID length: " + Hwid_Str.length());
```
### 5. 终端颜色打印PlusColorPrintlnPlus
在单行内打印多种颜色的文字包含Minecraft格式代码的文本
| 方法 | 说明 | 参数 |
|------------------------------------|----------------------|-----------------------------|
| `ColorPrintlnPlus(String Message)` | 仿照Minecraft类型的文本终端打印 | `message` 待打印的文本包含颜色与功能控制符 |
**使用示例**
```java
import top.gtb520.java.gnu.java.utils.library.utils.print.echo;
public class Main {
public static void main() {
echo.ColorPrintlnPlus("&dHello &2World&6!");
}
}
```
## 构建
```bash
mvn compile
```
```bash
mvn package
```
## 使用
编译成功后,将 `target/gnu-java-utils-library-1.0.0.jar` 放入项目依赖中。</br>
或者在releases中下载最新版jar包放入项目依赖中。
#### 使用示例:
**pom.xml**
```xml
<dependencies>
<!-- 引入本地依赖lib/gnu_java_utils_library-1.0-SNAPSHOT.jar -->
<dependency>
<groupId>top.gtb520.java.gnu</groupId>
<artifactId>gnu_java_utils_library</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>system</scope>
<!-- ${project.basedir} 为项目目录, /lib/ 为lib目录xxxx.jar 依赖的Jar包-->
<systemPath>${project.basedir}/lib/gnu_java_utils_library-1.0-SNAPSHOT.jar</systemPath>
</dependency>
</dependencies>
```
## 异常处理
@@ -120,4 +205,6 @@ mvn compile
## 许可证
本项目仅供学习与个人使用。
Apache License 2.0
禁止商业用途

View File

@@ -6,7 +6,7 @@
<groupId>top.gtb520.java.gnu</groupId>
<artifactId>gnu_java_utils_library</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.2-SNAPSHOT</version>
<properties>
<maven.compiler.source>25</maven.compiler.source>

View File

@@ -37,5 +37,30 @@ public interface main {
static void ColorHexPrintln(String Message, String ColorCode) {
top.gtb520.java.gnu.java.utils.library.utils.print.echo.ColorHexPrintln(Message, ColorCode);
}
// 在单行内打印多种颜色的文字包含Minecraft格式代码的文本仿照Minecraft类型的文本终端打印
static void ColorPrintlnPlus(String Message) {
top.gtb520.java.gnu.java.utils.library.utils.print.echo.ColorPrintlnPlus(Message);
}
}
// 随机数生成接口与方法
interface random {
// 默认随机数生成
static int defaule(int start_scope, int end_scope) {
return top.gtb520.java.gnu.java.utils.library.utils.processing.random.defaults.random(start_scope, end_scope);
}
// 生成指定长度的随机字符串
static String randomString(int length) {
return top.gtb520.java.gnu.java.utils.library.utils.processing.random.defaults.randomString(length);
}
}
// 硬件信息获取接口与方法HWID
interface hwid {
static String getHWID() {
return top.gtb520.java.gnu.java.utils.library.utils.processing.hwid.getHWID.generateHWID();
}
}
}

View File

@@ -1,5 +1,7 @@
package top.gtb520.java.gnu.java.utils.library.utils.print;
import java.util.concurrent.ThreadLocalRandom;
/**
* 终端彩色输出工具类
* 提供基于 ANSI 转义序列的终端彩色打印功能
@@ -8,14 +10,36 @@ public class echo {
// 终端彩色打印
/**
* 使用自定义十六进制颜色码在终端打印彩色文本
* 使用自定义颜色码在终端打印彩色文本
* 支持三种格式:
* - "#RRGGBB" 十六进制颜色(如 "#FFC0CB"
* - ANSI 颜色代码(如 "31" 表示红色)
* - ANSI 扩展色(如 "38;5;208" 表示扩展色)
*
* @param Message 要打印的文本内容
* @param HexColor ANSI 颜色代码(如 "31" 表示红色,"38;5;208" 表示扩展色
* @param HexColor 颜色代码,支持 "#RRGGBB"、ANSI 颜色代码或扩展色
*/
public static void ColorHexPrintln(String Message, String HexColor) {
if (HexColor.startsWith("#") && (HexColor.length() == 7 || HexColor.length() == 4)) {
// #RRGGBB 或 #RGB 格式,转换为 ANSI 真彩色序列
String hex = HexColor.substring(1);
int r, g, b;
if (hex.length() == 3) {
// #RGB 简写格式,将每个字符扩展为两位(如 F -> FF
r = Integer.parseInt(String.valueOf(hex.charAt(0)), 16) * 17;
g = Integer.parseInt(String.valueOf(hex.charAt(1)), 16) * 17;
b = Integer.parseInt(String.valueOf(hex.charAt(2)), 16) * 17;
} else {
r = Integer.parseInt(hex.substring(0, 2), 16);
g = Integer.parseInt(hex.substring(2, 4), 16);
b = Integer.parseInt(hex.substring(4, 6), 16);
}
System.out.println("\033[38;2;" + r + ";" + g + ";" + b + "m" + Message + "\033[0m");
} else {
// 原有 ANSI 颜色代码直接拼接
System.out.println("\033[" + HexColor + "m" + Message + "\033[0m");
}
}
/**
* 使用预定义的颜色名称在终端打印彩色文本
@@ -49,4 +73,112 @@ public class echo {
System.out.println(Message);
}
}
/**
* 在单行内打印多种颜色的文字
*
* 颜色代码仿照Minecraft格式
* &4红色、&c浅红色
* &6橙色、&e黄色
* &2绿色、&a浅绿色
* &b浅青色、&3深青色
* &1蓝色、&9浅蓝色
* &d粉色、&5紫色
* &f白色、&7灰色
* &8深灰色、&0黑色
* &l加粗、&n下划线
* &o斜体、&k乱码
* &m删除线、&r重置
*
* 示例:&6Welcome &2to &4Project
*
* @param Message 包含Minecraft格式代码的文本
*/
public static void ColorPrintlnPlus(String Message) {
if (Message == null) {
System.out.println();
return;
}
StringBuilder result = new StringBuilder();
boolean obfuscated = false;
int i = 0;
while (i < Message.length()) {
// 检测格式代码:& 后跟一个字符
if (Message.charAt(i) == '&' && i + 1 < Message.length()) {
char code = Character.toLowerCase(Message.charAt(i + 1));
String ansi = getAnsiCode(code);
if (ansi != null) {
// 先重置,再应用新格式(避免格式叠加冲突)
result.append("\033[0m");
result.append(ansi);
// &k 开启乱码模式,其他颜色/格式码关闭乱码模式
obfuscated = (code == 'k');
i += 2;
continue;
}
}
// 普通字符
char ch = Message.charAt(i);
if (obfuscated && ch != '\n' && ch != '\r') {
// 乱码模式:将可见字符替换为随机字符
result.append(randomChar());
} else {
result.append(ch);
}
i++;
}
// 结尾重置格式
result.append("\033[0m");
System.out.println(result.toString());
}
/**
* 根据 Minecraft 格式代码字符返回对应的 ANSI 转义序列
*
* @param code & 后的小写字符
* @return ANSI 转义序列,若字符不是合法格式代码则返回 null
*/
private static String getAnsiCode(char code) {
switch (code) {
// ===== 颜色码 =====
case '0': return "\033[30m"; // 黑色
case '1': return "\033[34m"; // 深蓝色
case '2': return "\033[32m"; // 深绿色
case '3': return "\033[36m"; // 深青色
case '4': return "\033[31m"; // 深红色
case '5': return "\033[35m"; // 深紫色
case '6': return "\033[38;5;214m"; // 橙色Gold
case '7': return "\033[37m"; // 灰色
case '8': return "\033[90m"; // 深灰色
case '9': return "\033[94m"; // 浅蓝色
case 'a': return "\033[92m"; // 浅绿色
case 'b': return "\033[96m"; // 浅青色
case 'c': return "\033[91m"; // 浅红色
case 'd': return "\033[95m"; // 粉色
case 'e': return "\033[93m"; // 黄色
case 'f': return "\033[97m"; // 白色
// ===== 格式码 =====
case 'l': return "\033[1m"; // 加粗
case 'm': return "\033[9m"; // 删除线
case 'n': return "\033[4m"; // 下划线
case 'o': return "\033[3m"; // 斜体
case 'k': return "\033[8m"; // 乱码(隐藏文字,配合随机字符替换实现)
case 'r': return "\033[0m"; // 重置
default: return null; // 非合法格式码,原样保留
}
}
/**
* 生成一个随机可见字符,用于乱码模式
*
* @return 随机可见字符
*/
private static char randomChar() {
// 从可打印 ASCII 字符范围33~126中随机选取
return (char) ThreadLocalRandom.current().nextInt(33, 127);
}
}

View File

@@ -0,0 +1,426 @@
package top.gtb520.java.gnu.java.utils.library.utils.processing.hwid;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.net.NetworkInterface;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class getHWID {
private final static boolean Debug = false;
/**
* 生成硬件标识符(HWID)
* 组合CPU、主板、MAC地址等信息生成唯一标识
*/
public static String generateHWID() {
try {
List<String> hardwareInfo = new ArrayList<>();
// 1. 获取CPU信息
String cpuInfo = getCPUInfo();
if (cpuInfo != null && !cpuInfo.isEmpty()) {
hardwareInfo.add("CPU:" + cpuInfo);
}
// 2. 获取主板序列号
String motherboardInfo = getMotherboardInfo();
if (motherboardInfo != null && !motherboardInfo.isEmpty()) {
hardwareInfo.add("MB:" + motherboardInfo);
}
// 3. 获取MAC地址
String macAddress = getMacAddress();
if (macAddress != null && !macAddress.isEmpty()) {
hardwareInfo.add("MAC:" + macAddress);
}
// 4. 获取硬盘序列号
String diskInfo = getDiskSerialNumber();
if (diskInfo != null && !diskInfo.isEmpty()) {
hardwareInfo.add("DISK:" + diskInfo);
}
// 5. 获取操作系统信息
String osInfo = System.getProperty("os.name") + "_" +
System.getProperty("os.version");
hardwareInfo.add("OS:" + osInfo);
// 6. 组合所有硬件信息并生成哈希
StringBuilder combined = new StringBuilder();
for (String info : hardwareInfo) {
if (Debug) {
System.out.println("info: " + info);
System.out.println("hardwareInfo: " + hardwareInfo);
System.out.println("combined: " + combined);
}
combined.append(info).append("|");
}
if (Debug) {
System.out.println("HWID combined: " + combined.toString());
}
// 使用SHA-256生成固定长度的哈希值
return generateHash(combined.toString());
} catch (Exception e) {
e.printStackTrace();
return "UNKNOWN_HWID";
}
}
/**
* 检测是否为Android系统
*/
private static boolean isAndroid() {
try {
String osName = System.getProperty("os.name").toLowerCase();
String javaVmName = System.getProperty("java.vm.name", "").toLowerCase();
String javaSpecVendor = System.getProperty("java.specification.vendor", "").toLowerCase();
// 通过多个特征判断是否为Android
return osName.contains("android") ||
javaVmName.contains("android") ||
javaSpecVendor.contains("android") ||
new java.io.File("/system/bin/app_process").exists();
} catch (Exception e) {
return false;
}
}
/**
* 获取CPU信息
*/
private static String getCPUInfo() {
try {
// Android系统特殊处理
if (isAndroid()) {
return getAndroidCPUInfo();
}
String os = System.getProperty("os.name").toLowerCase();
Process process;
if (os.contains("win")) {
// Windows: 获取ProcessorId
process = Runtime.getRuntime().exec(
new String[]{"wmic", "cpu", "get", "ProcessorId"}
);
} else if (os.contains("mac")) {
// macOS
process = Runtime.getRuntime().exec(
new String[]{"/usr/sbin/sysctl", "-n", "machdep.cpu.brand_string"}
);
} else {
// Linux: 获取CPU型号
process = Runtime.getRuntime().exec(
new String[]{"cat", "/proc/cpuinfo"}
);
}
process.waitFor();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
String line;
StringBuilder result = new StringBuilder();
while ((line = reader.readLine()) != null) {
line = line.trim();
if (!line.isEmpty()) {
if (os.contains("win") && !line.equals("ProcessorId")) {
return line;
} else if (os.contains("mac")) {
return line;
} else if (line.startsWith("model name")) {
return line.split(":", 2)[1].trim();
}
}
}
} catch (Exception e) {
// 静默失败返回null
}
return null;
}
/**
* 获取Android CPU信息
*/
private static String getAndroidCPUInfo() {
StringBuilder cpuInfo = new StringBuilder();
try {
// 方法1: 读取 /proc/cpuinfo
BufferedReader reader = new BufferedReader(new FileReader("/proc/cpuinfo"));
String line;
List<String> infoList = new ArrayList<>();
while ((line = reader.readLine()) != null) {
line = line.trim();
// 提取关键信息
if (line.startsWith("Processor") || line.startsWith("model name")) {
String[] parts = line.split(":", 2);
if (parts.length > 1) {
infoList.add("Processor:" + parts[1].trim());
}
} else if (line.startsWith("Hardware")) {
String[] parts = line.split(":", 2);
if (parts.length > 1) {
infoList.add("Hardware:" + parts[1].trim());
}
} else if (line.startsWith("CPU implementer")) {
String[] parts = line.split(":", 2);
if (parts.length > 1) {
infoList.add("Implementer:" + parts[1].trim());
}
} else if (line.startsWith("CPU architecture")) {
String[] parts = line.split(":", 2);
if (parts.length > 1) {
infoList.add("Architecture:" + parts[1].trim());
}
} else if (line.startsWith("CPU variant")) {
String[] parts = line.split(":", 2);
if (parts.length > 1) {
infoList.add("Variant:" + parts[1].trim());
}
} else if (line.startsWith("CPU part")) {
String[] parts = line.split(":", 2);
if (parts.length > 1) {
infoList.add("Part:" + parts[1].trim());
}
}
}
reader.close();
if (!infoList.isEmpty()) {
return String.join("|", infoList);
}
} catch (Exception e) {
// 静默失败
}
// 方法2: 如果读取文件失败使用System.getProperty
try {
String abi = System.getProperty("os.arch", "unknown");
String cores = Runtime.getRuntime().availableProcessors() + "";
return "ABI:" + abi + "|Cores:" + cores;
} catch (Exception e) {
return null;
}
}
/**
* 获取主板信息
*/
private static String getMotherboardInfo() {
try {
// Android系统特殊处理
if (isAndroid()) {
return getAndroidMotherboardInfo();
}
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
Process process = Runtime.getRuntime().exec(
new String[]{"wmic", "baseboard", "get", "SerialNumber"}
);
process.waitFor();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (!line.isEmpty() && !line.equals("SerialNumber")) {
return line;
}
}
}
} catch (Exception e) {
// 静默失败
}
return null;
}
/**
* 获取Android主板信息
*/
private static String getAndroidMotherboardInfo() {
try {
List<String> infoList = new ArrayList<>();
// 读取Android设备特性
String brand = System.getProperty("ro.product.brand", "");
String manufacturer = System.getProperty("ro.product.manufacturer", "");
String model = System.getProperty("ro.product.model", "");
String device = System.getProperty("ro.product.device", "");
String board = System.getProperty("ro.product.board", "");
if (!brand.isEmpty()) infoList.add("Brand:" + brand);
if (!manufacturer.isEmpty()) infoList.add("Manufacturer:" + manufacturer);
if (!model.isEmpty()) infoList.add("Model:" + model);
if (!device.isEmpty()) infoList.add("Device:" + device);
if (!board.isEmpty()) infoList.add("Board:" + board);
if (!infoList.isEmpty()) {
return String.join("|", infoList);
}
} catch (Exception e) {
// 静默失败
}
return null;
}
/**
* 获取MAC地址
*/
private static String getMacAddress() {
try {
Enumeration<NetworkInterface> networkInterfaces =
NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface network = networkInterfaces.nextElement();
byte[] mac = network.getHardwareAddress();
if (mac != null && mac.length > 0) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
sb.append(String.format("%02X%s", mac[i],
(i < mac.length - 1) ? "-" : ""));
}
return sb.toString();
}
}
} catch (Exception e) {
// 静默失败
}
return null;
}
/**
* 获取硬盘序列号
*/
private static String getDiskSerialNumber() {
try {
// Android系统特殊处理
if (isAndroid()) {
return getAndroidStorageInfo();
}
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
Process process = Runtime.getRuntime().exec(
new String[]{"wmic", "diskdrive", "get", "SerialNumber"}
);
process.waitFor();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (!line.isEmpty() && !line.equals("SerialNumber")) {
return line;
}
}
} else if (os.contains("mac") || os.contains("linux")) {
Process process = Runtime.getRuntime().exec(
new String[]{"sh", "-c", "system_profiler SPSerialATADataType | grep 'Serial Number'"}
);
process.waitFor();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream())
);
String line;
if ((line = reader.readLine()) != null) {
if (line.contains(":")) {
return line.split(":", 2)[1].trim();
}
}
}
} catch (Exception e) {
// 静默失败
}
return null;
}
/**
* 获取Android存储信息
*/
private static String getAndroidStorageInfo() {
try {
// 读取 /proc/mounts 或使用系统属性
List<String> infoList = new ArrayList<>();
// 尝试获取存储相关信息
String internalStorage = System.getProperty("user.dir", "");
if (!internalStorage.isEmpty()) {
infoList.add("InternalDir:" + internalStorage);
}
// 检查外部存储是否可用
java.io.File externalStorage = new java.io.File("/sdcard");
if (externalStorage.exists()) {
infoList.add("ExternalStorage:available");
} else {
infoList.add("ExternalStorage:not_available");
}
// 获取数据目录
java.io.File dataDir = new java.io.File("/data");
if (dataDir.exists()) {
infoList.add("DataDir:exists");
}
if (!infoList.isEmpty()) {
return String.join("|", infoList);
}
} catch (Exception e) {
// 静默失败
}
return null;
}
/**
* 使用SHA-256生成哈希值
*/
private static String generateHash(String input) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(input.getBytes("UTF-8"));
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (Exception e) {
e.printStackTrace();
return input.hashCode() + "";
}
}
}

View File

@@ -0,0 +1,48 @@
package top.gtb520.java.gnu.java.utils.library.utils.processing.random;
import java.util.concurrent.ThreadLocalRandom;
public class defaults {
/**
* 根据输入的范围生成随机数
* @param start_scope 起始范围
* @param end_scope 结束范围
* @return 随机数
*/
public static int random(int start_scope, int end_scope) {
int random_double;
// 处理边界,确保起始范围小于等于结束范围
if (start_scope > end_scope) {
System.out.println("起始范围不能大于结束范围");
throw new IllegalArgumentException("起始范围不能大于结束范围");
}
// 生成随机数
random_double = ThreadLocalRandom.current().nextInt(start_scope, end_scope + 1);
return random_double;
}
/**
* 生成指定长度的随机字符串
* @param length 字符串长度
* @return 随机字符串
*/
public static String randomString(int length) {
String alphabetsInUpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String alphabetsInLowerCase = "abcdefghijklmnopqrstuvwxyz";
String numbers = "0123456789";
// create a super set of all characters
String allCharacters = alphabetsInLowerCase + alphabetsInUpperCase + numbers;
// initialize a string to hold result
StringBuffer randomString = new StringBuffer();
// loop for 10 times
for (int i = 0; i < length; i++) {
// generate a random number between 0 and length of all characters
int randomIndex = (int)(Math.random() * allCharacters.length());
// retrieve character at index and add it to result
randomString.append(allCharacters.charAt(randomIndex));
}
return randomString.toString();
}
}

View File

@@ -0,0 +1,7 @@
import top.gtb520.java.gnu.java.utils.library.utils.print.echo;
public class ColorPrintlnPlusTest2 {
public static void main() {
echo.ColorPrintlnPlus("&dHello &2World&6!");
}
}

View File

@@ -0,0 +1,16 @@
import top.gtb520.java.gnu.java.utils.library.main;
import top.gtb520.java.gnu.java.utils.library.utils.processing.hwid.getHWID;
public class HwidTest {
public static void main() {
String Hwid_Str;
Hwid_Str = main.hwid.getHWID();
System.out.println("HWID: " + Hwid_Str);
System.out.println("HWID length: " + Hwid_Str.length());
String Hwid_Str2;
Hwid_Str2 = getHWID.generateHWID();
System.out.println("HWID: " + Hwid_Str2);
System.out.println("HWID length: " + Hwid_Str2.length());
}
}

View File

@@ -9,5 +9,16 @@ public class echo {
main.echo.Println("PURPLE", ColorNameEnum.PURPLE);
main.echo.Println("GREEN", ColorNameEnum.GREEN);
main.echo.Println("RED", ColorNameEnum.RED);
ColorHexPrintlnTest();
System.out.println("111111111111111111");
main.echo.Println("头上带点绿,生活过得去", ColorNameEnum.GREEN);
}
static void ColorHexPrintlnTest() {
main.echo.ColorHexPrintln("ColorHexPrintlnTest_RED", "31");
main.echo.ColorHexPrintln("自定义橙色", "38;5;208");
main.echo.ColorHexPrintln("十六进制粉色", "#FFC0CB");
}
}

View File

@@ -0,0 +1,32 @@
import top.gtb520.java.gnu.java.utils.library.main;
import top.gtb520.java.gnu.java.utils.library.utils.print.ColorNameEnum;
public class echoTest {
public static void main(String[] args) {
System.out.println("========== echo 测试开始 ==========");
// 测试 #RRGGBB 格式
main.echo.ColorHexPrintln("十六进制粉色 #FFC0CB", "#FFC0CB");
main.echo.ColorHexPrintln("十六进制红色 #FF0000", "#FF0000");
main.echo.ColorHexPrintln("十六进制绿色 #00FF00", "#00FF00");
main.echo.ColorHexPrintln("十六进制蓝色 #0000FF", "#0000FF");
// 测试 #RGB 简写格式
main.echo.ColorHexPrintln("RGB简写粉色 #F0F", "#F0F");
main.echo.ColorHexPrintln("RGB简写白色 #FFF", "#FFF");
// 测试原有 ANSI 颜色代码(兼容性)
main.echo.ColorHexPrintln("ANSI红色 31", "31");
main.echo.ColorHexPrintln("ANSI扩展色 38;5;208", "38;5;208");
// 测试预定义颜色枚举
main.echo.Println("枚举红色", ColorNameEnum.RED);
main.echo.Println("枚举蓝色", ColorNameEnum.BLUE);
main.echo.Println("枚举绿色", ColorNameEnum.GREEN);
main.echo.Println("枚举黄色", ColorNameEnum.YELLOW);
main.echo.Println("枚举青色", ColorNameEnum.CYAN);
main.echo.Println("枚举紫色", ColorNameEnum.PURPLE);
System.out.println("========== echo 测试完成 ==========");
}
}

View File

@@ -0,0 +1,335 @@
package top.gtb520.java.gnu.java.utils.library.utils.print;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
public class ColorPrintlnPlusTest {
static int passed = 0;
static int failed = 0;
public static void main(String[] args) {
System.out.println("========== ColorPrintlnPlus 测试开始 ==========");
testNullInput();
testPlainMessageNoFormatCode();
testSingleColorCode();
testMultipleColorCodes();
testFormatCodeBold();
testFormatCodeUnderline();
testFormatCodeItalic();
testFormatCodeStrikethrough();
testFormatCodeReset();
testObfuscatedMode();
testObfuscatedModeDifferentEachCall();
testObfuscatedModeTurnsOffOnNewCode();
testInvalidCodeKeptAsIs();
testAmpersandAtEndOfString();
testCaseInsensitiveCodes();
testAllColorCodes();
testVisualOutput();
System.out.println("========================================");
System.out.println("测试完成: 通过 " + passed + ", 失败 " + failed);
if (failed > 0) {
System.exit(1);
}
}
/**
* 捕获 ColorPrintlnPlus 输出到字符串
*/
static String captureOutput(String input) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream original = System.out;
System.setOut(new PrintStream(baos));
try {
echo.ColorPrintlnPlus(input);
} finally {
System.setOut(original);
}
return baos.toString();
}
/**
* 测试 null 输入
*/
static void testNullInput() {
String testName = "testNullInput";
try {
String output = captureOutput(null);
assertCondition(testName + " - null输入应输出空行", output.trim().isEmpty());
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试无格式代码的纯文本
*/
static void testPlainMessageNoFormatCode() {
String testName = "testPlainMessageNoFormatCode";
try {
String output = captureOutput("Hello World");
assertCondition(testName + " - 应包含原文本", output.contains("Hello World"));
assertCondition(testName + " - 应以重置序列结尾", output.contains("\033[0m"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试单个颜色代码
*/
static void testSingleColorCode() {
String testName = "testSingleColorCode";
try {
String output = captureOutput("&4Red Text");
// &4 应转换为深红色 ANSI 序列 \033[31m
assertCondition(testName + " - 应包含红色ANSI序列", output.contains("\033[31m"));
assertCondition(testName + " - 应包含文本内容", output.contains("Red Text"));
assertCondition(testName + " - 不应包含格式代码&4", !output.contains("&4"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试多个颜色代码
*/
static void testMultipleColorCodes() {
String testName = "testMultipleColorCodes";
try {
String output = captureOutput("&6Welcome &2to &4Project");
// &6 → 橙色 \033[38;5;214m
assertCondition(testName + " - 应包含橙色ANSI序列", output.contains("\033[38;5;214m"));
// &2 → 深绿色 \033[32m
assertCondition(testName + " - 应包含深绿色ANSI序列", output.contains("\033[32m"));
// &4 → 深红色 \033[31m
assertCondition(testName + " - 应包含深红色ANSI序列", output.contains("\033[31m"));
assertCondition(testName + " - 应包含Welcome", output.contains("Welcome"));
assertCondition(testName + " - 应包含to", output.contains("to"));
assertCondition(testName + " - 应包含Project", output.contains("Project"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试加粗格式码 &l
*/
static void testFormatCodeBold() {
String testName = "testFormatCodeBold";
try {
String output = captureOutput("&lBold Text");
assertCondition(testName + " - 应包含加粗ANSI序列", output.contains("\033[1m"));
assertCondition(testName + " - 应包含文本", output.contains("Bold Text"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试下划线格式码 &n
*/
static void testFormatCodeUnderline() {
String testName = "testFormatCodeUnderline";
try {
String output = captureOutput("&nUnderlined");
assertCondition(testName + " - 应包含下划线ANSI序列", output.contains("\033[4m"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试斜体格式码 &o
*/
static void testFormatCodeItalic() {
String testName = "testFormatCodeItalic";
try {
String output = captureOutput("&oItalic");
assertCondition(testName + " - 应包含斜体ANSI序列", output.contains("\033[3m"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试删除线格式码 &m
*/
static void testFormatCodeStrikethrough() {
String testName = "testFormatCodeStrikethrough";
try {
String output = captureOutput("&mStrike");
assertCondition(testName + " - 应包含删除线ANSI序列", output.contains("\033[9m"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试重置格式码 &r
*/
static void testFormatCodeReset() {
String testName = "testFormatCodeReset";
try {
String output = captureOutput("&4Red&r Normal");
// &r 应产生重置序列 \033[0m
assertCondition(testName + " - 应包含重置序列", output.contains("\033[0m"));
assertCondition(testName + " - 应包含Normal", output.contains("Normal"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试乱码模式 &k字符被替换为随机字符
*/
static void testObfuscatedMode() {
String testName = "testObfuscatedMode";
try {
String output = captureOutput("&kSecret");
// 输出不应包含原始文本 "Secret"(因为被替换为随机字符)
// 但应包含乱码ANSI序列 \033[8m
assertCondition(testName + " - 应包含乱码ANSI序列", output.contains("\033[8m"));
// 输出中"Secret"被替换长度应与原词相同6个字符区域
assertCondition(testName + " - 不应包含原始文本Secret", !output.contains("Secret"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试乱码模式每次调用产生不同结果
*/
static void testObfuscatedModeDifferentEachCall() {
String testName = "testObfuscatedModeDifferentEachCall";
try {
String output1 = captureOutput("&kAAAAAAAAAA");
String output2 = captureOutput("&kAAAAAAAAAA");
// 两次调用的乱码结果应不同10个字符全部随机几乎不可能相同
assertCondition(testName + " - 两次调用应产生不同乱码", !output1.equals(output2));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试乱码模式在遇到新格式码时关闭
*/
static void testObfuscatedModeTurnsOffOnNewCode() {
String testName = "testObfuscatedModeTurnsOffOnNewCode";
try {
String output = captureOutput("&kHidden&aVisible");
// &a 应关闭乱码并开启绿色
assertCondition(testName + " - 应包含绿色ANSI序列", output.contains("\033[92m"));
// "Visible" 应保持原文
assertCondition(testName + " - 新格式码后的文本应保持原文", output.contains("Visible"));
// "Hidden" 不应出现
assertCondition(testName + " - 乱码区域的文本不应出现", !output.contains("Hidden"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试非合法格式码保持原样
*/
static void testInvalidCodeKeptAsIs() {
String testName = "testInvalidCodeKeptAsIs";
try {
String output = captureOutput("&zUnknown");
// &z 不是合法格式码,应保持原样
assertCondition(testName + " - 非合法格式码应保持原样", output.contains("&zUnknown"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试 & 在字符串末尾
*/
static void testAmpersandAtEndOfString() {
String testName = "testAmpersandAtEndOfString";
try {
String output = captureOutput("Text&");
// 末尾的 & 后无字符,应保持原样
assertCondition(testName + " - 末尾的&应保持原样", output.contains("Text&"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试格式码大小写不敏感
*/
static void testCaseInsensitiveCodes() {
String testName = "testCaseInsensitiveCodes";
try {
String outputLower = captureOutput("&4red");
String outputUpper = captureOutput("&4red");
assertCondition(testName + " - 小写格式码应正常工作", outputLower.contains("\033[31m"));
assertCondition(testName + " - 大写格式码应正常工作", outputUpper.contains("\033[31m"));
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试所有16种颜色码均能正确转换
*/
static void testAllColorCodes() {
String testName = "testAllColorCodes";
String[][] colorMap = {
{"0", "\033[30m"}, {"1", "\033[34m"}, {"2", "\033[32m"}, {"3", "\033[36m"},
{"4", "\033[31m"}, {"5", "\033[35m"}, {"6", "\033[38;5;214m"}, {"7", "\033[37m"},
{"8", "\033[90m"}, {"9", "\033[94m"}, {"a", "\033[92m"}, {"b", "\033[96m"},
{"c", "\033[91m"}, {"d", "\033[95m"}, {"e", "\033[93m"}, {"f", "\033[97m"}
};
try {
boolean allPassed = true;
for (String[] pair : colorMap) {
String output = captureOutput("&" + pair[0] + "x");
if (!output.contains(pair[1])) {
assertCondition(testName + " - &" + pair[0] + " 应转换为 " + pair[1], false);
allPassed = false;
}
}
if (allPassed) {
assertCondition(testName + " - 全部16种颜色码转换正确", true);
}
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 视觉测试:在终端直接展示各种效果
*/
static void testVisualOutput() {
System.out.println("--- 视觉测试(请人工确认)---");
echo.ColorPrintlnPlus("&4深红色 &c浅红色 &6橙色 &e黄色 &2深绿色 &a浅绿色");
echo.ColorPrintlnPlus("&b浅青色 &3深青色 &1深蓝色 &9浅蓝色 &d粉色 &5深紫色");
echo.ColorPrintlnPlus("&f白色 &7灰色 &8深灰色 &0黑色");
echo.ColorPrintlnPlus("&l加粗文字 &n下划线文字 &o斜体文字 &m删除线文字");
echo.ColorPrintlnPlus("&6Welcome &2to &4Project");
echo.ColorPrintlnPlus("&k这是一段乱码文字每次不同");
echo.ColorPrintlnPlus("&4红色 &l加粗红色 &r重置为普通");
System.out.println("--- 视觉测试结束 ---");
// 视觉测试直接计为通过
passed++;
}
// ========== 辅助方法 ==========
static void assertCondition(String message, boolean condition) {
if (condition) {
System.out.println("[PASS] " + message);
passed++;
} else {
System.out.println("[FAIL] " + message);
failed++;
}
}
}

View File

@@ -0,0 +1,47 @@
package top.gtb520.java.gnu.java.utils.library.utils.processing.random;
import top.gtb520.java.gnu.java.utils.library.main;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom;
// 毫无意义的随机数测试代码,在循环中执行随机数生成 10 亿次
public class Test {
public static void main(String[] args) {
int totalTasks = 1_000_000_000;
// 根据CPU核心数创建固定大小的线程池避免创建过多线程导致上下文切换开销
int threadCount = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
// 将总任务量平均分配给每个线程
int tasksPerThread = totalTasks / threadCount;
for (int t = 0; t < threadCount; t++) {
final int start = t * tasksPerThread;
// 处理余数,确保最后一个线程承担剩余任务
final int end = (t == threadCount - 1) ? totalTasks : start + tasksPerThread;
executor.submit(() -> {
// 【核心优化1】使用 ThreadLocalRandom 替代共享 Random
// 每个线程拥有独立的 seed完全无锁避免高并发下的 CAS 竞争
ThreadLocalRandom random = ThreadLocalRandom.current();
// 【核心优化2】将 I/O 与计算分离
// 在实际业务中,应只返回计算结果,而不是在循环中打印
for (int i = start; i < end; i++) {
int random_i = random.nextInt(1, 1000000001); // [1, 1000000000]
// 如果确实需要输出建议降低频率例如每1000万次输出一次
// if (i % 10000 == 0) {
// System.out.println("随机数: " + random_i + " 当前循环位置: " + i);
// }
System.out.println("随机数: " + random_i + " 当前循环位置: " + i);
}
});
}
// 优雅关闭线程池
executor.shutdown();
}
}

View File

@@ -0,0 +1,142 @@
package top.gtb520.java.gnu.java.utils.library.utils.processing.random;
public class defauleTest {
static int passed = 0;
static int failed = 0;
public static void main(String[] args) {
System.out.println("========== defaults.random 测试开始 ==========");
testRandomInRange();
testRandomSameStartAndEnd();
testRandomNegativeRange();
testRandomReversedRange();
testRandomLargeRange();
testRandomDistribution();
System.out.println("========================================");
System.out.println("测试完成: 通过 " + passed + ", 失败 " + failed);
if (failed > 0) {
System.exit(1);
}
}
/**
* 测试正常范围内的随机数
*/
static void testRandomInRange() {
String testName = "testRandomInRange";
try {
for (int i = 0; i < 100; i++) {
int result = defaults.random(1, 10);
if (result < 1 || result > 10) {
assertCondition(testName + " - 随机数应在[1,10]范围内,实际: " + result, false);
return;
}
}
assertCondition(testName + " - 100次随机数均在[1,10]范围内", true);
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试起始值等于结束值
*/
static void testRandomSameStartAndEnd() {
String testName = "testRandomSameStartAndEnd";
try {
int result = defaults.random(5, 5);
assertCondition(testName + " - 结果应等于5实际: " + result, result == 5);
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试负数范围
*/
static void testRandomNegativeRange() {
String testName = "testRandomNegativeRange";
try {
for (int i = 0; i < 100; i++) {
int result = defaults.random(-10, -1);
if (result < -10 || result > -1) {
assertCondition(testName + " - 随机数应在[-10,-1]范围内,实际: " + result, false);
return;
}
}
assertCondition(testName + " - 100次随机数均在[-10,-1]范围内", true);
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试起始值大于结束值应抛出异常
*/
static void testRandomReversedRange() {
String testName = "testRandomReversedRange";
try {
defaults.random(10, 1);
assertCondition(testName + " - 应抛出IllegalArgumentException", false);
} catch (IllegalArgumentException e) {
assertCondition(testName + " - 应抛出IllegalArgumentException", true);
} catch (Exception e) {
assertCondition(testName + " - 异常类型不正确: " + e.getClass().getName(), false);
}
}
/**
* 测试大范围随机数
*/
static void testRandomLargeRange() {
String testName = "testRandomLargeRange";
try {
for (int i = 0; i < 100; i++) {
int result = defaults.random(-1000000, 1000000);
if (result < -1000000 || result > 1000000) {
assertCondition(testName + " - 随机数超出范围,实际: " + result, false);
return;
}
}
assertCondition(testName + " - 100次随机数均在[-1000000,1000000]范围内", true);
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
/**
* 测试随机数分布(验证不会总是返回同一个值)
*/
static void testRandomDistribution() {
String testName = "testRandomDistribution";
try {
int first = defaults.random(1, 1000000);
boolean hasDifferent = false;
for (int i = 0; i < 100; i++) {
int result = defaults.random(1, 1000000);
if (result != first) {
hasDifferent = true;
break;
}
}
assertCondition(testName + " - 100次调用应产生不同随机数", hasDifferent);
} catch (Exception e) {
assertCondition(testName + " - 不应抛出异常: " + e.getMessage(), false);
}
}
// ========== 辅助方法 ==========
static void assertCondition(String message, boolean condition) {
if (condition) {
System.out.println("[PASS] " + message);
passed++;
} else {
System.out.println("[FAIL] " + message);
failed++;
}
}
}

View File

@@ -0,0 +1,8 @@
package top.gtb520.java.gnu.java.utils.library.utils.processing.random;
public class randomStringTest {
public static void main(String[] args) {
defaults.random(1, 100);
defaults.randomString(10);
}
}