Compare commits
28 Commits
1.0-SNAPSH
...
1.3-SNAPSH
| Author | SHA1 | Date | |
|---|---|---|---|
| 3ec2e132c3 | |||
| c8462d5c68 | |||
| 441891652c | |||
| 03e223df9b | |||
| 0304fed324 | |||
| 6934ac8663 | |||
| 072d2a841b | |||
| 4fd86d332f | |||
| eadcca5b59 | |||
| e557dcde11 | |||
| 00b0636a0d | |||
| ac361cebcf | |||
| 9ebb6f8354 | |||
| d73881fd86 | |||
| 1e577622b3 | |||
| a2bfbf1005 | |||
| 31024f33c5 | |||
| 8ce618e03d | |||
| b2e94b3b86 | |||
| 720ccf1952 | |||
| ba1cbc9674 | |||
| 949030d606 | |||
| 350f59bfe2 | |||
| 907bde792a | |||
| 2ff9313a2a | |||
| 7420b84f5f | |||
| 4980f0d1f6 | |||
| c1d105939b |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -38,6 +38,8 @@ build/
|
|||||||
### Mac OS ###
|
### Mac OS ###
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
### Other ###
|
||||||
/target
|
/target
|
||||||
/.idea
|
/.idea
|
||||||
/.mvn
|
/.mvn
|
||||||
|
/build_release
|
||||||
4
NOTICE
Normal file
4
NOTICE
Normal 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许可协议。
|
||||||
295
README.md
295
README.md
@@ -1,38 +1,51 @@
|
|||||||
# GNU Java Utils Library
|
# GNU Java Utils Library
|
||||||
|
|
||||||
一个轻量级 Java 工具库,提供常用的压缩/解压与终端彩色输出功能。
|
一个轻量级 Java 工具库,提供压缩/解压、终端彩色输出、随机数生成、硬件标识等功能。
|
||||||
|
|
||||||
|
> 注:此项目/仓库已同步到 Github:[https://github.com/databasemysql233-debug/gnu_java_utils_library.git](https://github.com/databasemysql233-debug/gnu_java_utils_library.git)
|
||||||
|
> 原项目/仓库链接:[https://git.opensource-studio.info/database-mysql/gnu_java_utils_library.git](https://git.opensource-studio.info/database-mysql/gnu_java_utils_library.git)
|
||||||
|
|
||||||
## 技术栈
|
## 技术栈
|
||||||
|
|
||||||
- **Java 25**
|
- **Java 25**
|
||||||
- **Maven** 构建
|
- **Maven** 构建
|
||||||
- **Apache Commons Compress 1.28.0**(压缩功能依赖)
|
- **Apache Commons Compress 1.28.0**(压缩功能依赖)
|
||||||
|
- **JUnit Jupiter 5.13.0**(测试框架)
|
||||||
|
|
||||||
## 项目结构
|
## 项目结构
|
||||||
|
|
||||||
```
|
```
|
||||||
src/main/java/top/gtb520/java/gnu/java/utils/library/
|
src/main/java/top/gtb520/java/gnu/java/utils/library/
|
||||||
├── main.java # 统一入口接口
|
├── main.java # 统一入口接口
|
||||||
├── utils/
|
├── version.java # 项目版本信息
|
||||||
│ ├── compress/
|
└── utils/
|
||||||
│ │ └── compress.java # 压缩/解压工具类
|
├── compress/
|
||||||
│ └── print/
|
│ └── compress.java # 压缩/解压工具类
|
||||||
│ ├── echo.java # 终端彩色输出工具类
|
├── print/
|
||||||
│ └── ColorNameEnum.java # 颜色名称枚举
|
│ ├── echo.java # 终端彩色输出工具类
|
||||||
|
│ └── ColorNameEnum.java # 颜色名称枚举
|
||||||
|
└── processing/
|
||||||
|
├── random/
|
||||||
|
│ └── defaults.java # 随机数/字符串生成器
|
||||||
|
├── hwid/
|
||||||
|
│ └── getHWID.java # 硬件标识生成器
|
||||||
|
└── runtime/
|
||||||
|
├── RunEnv.java # 运行环境信息
|
||||||
|
└── JavaRunTimeEnv.java # Java 运行时环境信息
|
||||||
```
|
```
|
||||||
|
|
||||||
## 功能模块
|
## 功能模块
|
||||||
|
|
||||||
### 1. 压缩/解压 (`compress`)
|
### 1. 压缩/解压 (`compress`)
|
||||||
|
|
||||||
支持 **Tar.Gz** 和 **Zip** 两种压缩格式的压缩与解压操作,支持单文件和整个目录的递归处理。
|
支持 **Tar.Gz** 和 **Zip** 两种格式的压缩与解压,支持单文件和目录递归处理。
|
||||||
|
|
||||||
| 方法 | 说明 | 参数 |
|
| 方法 | 说明 | 参数 |
|
||||||
|------|------|------|
|
|------------------------------------|--------------------------|-------------------------------------|
|
||||||
| `compress.MakeTarGz(source, dest)` | 将文件或目录压缩为 `.tar.gz` | `source` 源路径,`dest` 压缩包输出路径 |
|
| `compress.MakeTarGz(source, dest)` | 将文件或目录压缩为 `.tar.gz` | `source` 源路径,`dest` 压缩包输出路径 |
|
||||||
| `compress.UnTarGz(source, dest)` | 解压 `.tar.gz` 到指定目录 | `source` 压缩包路径,`dest` 解压目标目录 |
|
| `compress.UnTarGz(source, dest)` | 解压 `.tar.gz` 到指定目录 | `source` 压缩包路径,`dest` 解压目标目录 |
|
||||||
| `compress.MakeZip(source, dest)` | 将文件或目录压缩为 `.zip` | `source` 源路径,`dest` 压缩包输出路径 |
|
| `compress.MakeZip(source, dest)` | 将文件或目录压缩为 `.zip` | `source` 源路径,`dest` 压缩包输出路径 |
|
||||||
| `compress.UnZip(source, dest)` | 解压 `.zip` 到指定目录 | `source` 压缩包路径,`dest` 解压目标目录 |
|
| `compress.UnZip(source, dest)` | 解压 `.zip` 到指定目录 | `source` 压缩包路径,`dest` 解压目标目录 |
|
||||||
|
|
||||||
**使用示例:**
|
**使用示例:**
|
||||||
|
|
||||||
@@ -63,46 +76,230 @@ main.compress.TarGz(source, dest);
|
|||||||
|
|
||||||
### 2. 终端彩色输出 (`echo`)
|
### 2. 终端彩色输出 (`echo`)
|
||||||
|
|
||||||
基于 ANSI 转义序列,在终端中输出彩色文本。
|
基于 ANSI 转义序列,在终端中输出彩色文本。提供三种打印方式:
|
||||||
|
|
||||||
| 方法 | 说明 | 参数 |
|
#### 2.1 预定义颜色打印 — `ColorPrintln`
|
||||||
|------|------|------|
|
|
||||||
| `echo.ColorPrintln(message, color)` | 使用预定义颜色打印 | `message` 文本内容,`color` 颜色枚举 |
|
使用颜色枚举快速输出。
|
||||||
| `echo.ColorHexPrintln(message, hexColor)` | 使用自定义 ANSI 颜色码打印 | `message` 文本内容,`hexColor` ANSI 颜色代码 |
|
|
||||||
|
| 方法 | 说明 | 参数 |
|
||||||
|
|-------------------------------------|-------------|--------------------------------|
|
||||||
|
| `echo.ColorPrintln(message, color)` | 使用预定义颜色打印 | `message` 文本,`color` 颜色枚举 |
|
||||||
|
|
||||||
**支持的颜色枚举 (`ColorNameEnum`):**
|
**支持的颜色枚举 (`ColorNameEnum`):**
|
||||||
|
|
||||||
| 枚举值 | 颜色 |
|
| 枚举值 | 颜色 |
|
||||||
|--------|------|
|
|----------|----|
|
||||||
| `RED` | 红色 |
|
| `RED` | 红色 |
|
||||||
| `GREEN` | 绿色 |
|
| `GREEN` | 绿色 |
|
||||||
| `YELLOW` | 黄色 |
|
| `YELLOW` | 黄色 |
|
||||||
| `BLUE` | 蓝色 |
|
| `BLUE` | 蓝色 |
|
||||||
| `PURPLE` | 紫色 |
|
| `PURPLE` | 紫色 |
|
||||||
| `CYAN` | 青色 |
|
| `CYAN` | 青色 |
|
||||||
|
|
||||||
**使用示例:**
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
import top.gtb520.java.gnu.java.utils.library.utils.print.echo;
|
import top.gtb520.java.gnu.java.utils.library.utils.print.echo;
|
||||||
import top.gtb520.java.gnu.java.utils.library.utils.print.ColorNameEnum;
|
import top.gtb520.java.gnu.java.utils.library.utils.print.ColorNameEnum;
|
||||||
|
|
||||||
// 使用预定义颜色
|
|
||||||
echo.ColorPrintln("错误信息", ColorNameEnum.RED);
|
echo.ColorPrintln("错误信息", ColorNameEnum.RED);
|
||||||
echo.ColorPrintln("成功信息", ColorNameEnum.GREEN);
|
echo.ColorPrintln("成功信息", ColorNameEnum.GREEN);
|
||||||
|
```
|
||||||
|
|
||||||
// 使用自定义 ANSI 颜色码
|
#### 2.2 自定义颜色打印 — `ColorHexPrintln`
|
||||||
echo.ColorHexPrintln("自定义橙色", "38;5;208");
|
|
||||||
|
支持 `#RRGGBB`、`#RGB` 十六进制颜色及 ANSI 颜色代码。
|
||||||
|
|
||||||
|
| 方法 | 说明 | 参数 |
|
||||||
|
|-------------------------------------------|------------------|-------------------------------------|
|
||||||
|
| `echo.ColorHexPrintln(message, hexColor)` | 使用自定义颜色码打印 | `message` 文本,`hexColor` 颜色代码 |
|
||||||
|
|
||||||
|
**支持的颜色格式:**
|
||||||
|
|
||||||
|
| 格式 | 示例 | 说明 |
|
||||||
|
|-------------|-------------|------------------------|
|
||||||
|
| `#RRGGBB` | `#FFC0CB` | 十六进制真彩色,自动转 ANSI 序列 |
|
||||||
|
| `#RGB` | `#F0F` | 十六进制简写,自动扩展后转 ANSI 序列 |
|
||||||
|
| ANSI 颜色码 | `31` | 标准 ANSI 颜色(如 31=红色) |
|
||||||
|
| ANSI 扩展色 | `38;5;208` | 256 色扩展(如 208=橙色) |
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 十六进制颜色
|
||||||
|
echo.ColorHexPrintln("粉色文本", "#FFC0CB");
|
||||||
|
echo.ColorHexPrintln("简写青色", "#0FF");
|
||||||
|
|
||||||
|
// ANSI 颜色码
|
||||||
|
echo.ColorHexPrintln("红色文本", "31");
|
||||||
|
echo.ColorHexPrintln("扩展橙色", "38;5;208");
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.3 Minecraft 风格多色打印 — `ColorPrintlnPlus`
|
||||||
|
|
||||||
|
在单行内使用 `&X` 格式码打印多种颜色和文本效果,仿照 Minecraft 格式化语法。
|
||||||
|
|
||||||
|
| 方法 | 说明 | 参数 |
|
||||||
|
|------------------------------------|-----------------------|-----------------------------|
|
||||||
|
| `echo.ColorPrintlnPlus(message)` | 解析 `&X` 格式码后打印多色文本 | `message` 含格式码的文本 |
|
||||||
|
|
||||||
|
**颜色代码:**
|
||||||
|
|
||||||
|
| 代码 | 颜色 | 代码 | 颜色 |
|
||||||
|
|------|--------|------|--------|
|
||||||
|
| `&0` | 黑色 | `&8` | 深灰色 |
|
||||||
|
| `&1` | 深蓝色 | `&9` | 浅蓝色 |
|
||||||
|
| `&2` | 深绿色 | `&a` | 浅绿色 |
|
||||||
|
| `&3` | 深青色 | `&b` | 浅青色 |
|
||||||
|
| `&4` | 深红色 | `&c` | 浅红色 |
|
||||||
|
| `&5` | 深紫色 | `&d` | 粉色 |
|
||||||
|
| `&6` | 橙色 | `&e` | 黄色 |
|
||||||
|
| `&7` | 灰色 | `&f` | 白色 |
|
||||||
|
|
||||||
|
**格式代码:**
|
||||||
|
|
||||||
|
| 代码 | 效果 | 代码 | 效果 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| `&l` | 加粗 | `&k` | 乱码(随机字符替换) |
|
||||||
|
| `&m` | 删除线 | `&r` | 重置 |
|
||||||
|
| `&n` | 下划线 | | |
|
||||||
|
| `&o` | 斜体 | | |
|
||||||
|
|
||||||
|
> 格式码大小写不敏感,`&A` 与 `&a` 等效。非合法格式码(如 `&z`)将原样保留。
|
||||||
|
|
||||||
|
```java
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.utils.print.echo;
|
||||||
|
|
||||||
|
// 多色文本
|
||||||
|
echo.ColorPrintlnPlus("&6Welcome &2to &4Project");
|
||||||
|
|
||||||
|
// 混合格式效果
|
||||||
|
echo.ColorPrintlnPlus("&4&l粗体红色 &n&9下划线蓝色");
|
||||||
|
|
||||||
|
// 乱码效果(每次调用生成不同随机字符)
|
||||||
|
echo.ColorPrintlnPlus("&k这是一段乱码文字");
|
||||||
|
|
||||||
|
// 重置后恢复普通文本
|
||||||
|
echo.ColorPrintlnPlus("&4红色文字 &r普通文字");
|
||||||
```
|
```
|
||||||
|
|
||||||
也可以通过统一入口 `main` 接口调用:
|
也可以通过统一入口 `main` 接口调用:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
import top.gtb520.java.gnu.java.utils.library.main;
|
import top.gtb520.java.gnu.java.utils.library.main;
|
||||||
import top.gtb520.java.gnu.java.utils.library.utils.print.ColorNameEnum;
|
|
||||||
|
|
||||||
main.echo.Println("警告信息", ColorNameEnum.YELLOW);
|
main.echo.Println("警告信息", ColorNameEnum.YELLOW);
|
||||||
main.echo.ColorHexPrintln("自定义颜色", "31");
|
main.echo.ColorHexPrintln("自定义颜色", "#FF0000");
|
||||||
|
main.echo.ColorPrintlnPlus("&a多色 &c文本");
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 随机生成器 (`random`)
|
||||||
|
|
||||||
|
| 方法 | 说明 | 参数 |
|
||||||
|
|---------------------------------------------|--------------|------------------------------|
|
||||||
|
| `defaults.random(start_scope, end_scope)` | 生成指定范围内的随机数 | `start_scope` 起始,`end_scope` 结束 |
|
||||||
|
| `defaults.randomString(length)` | 生成指定长度的随机字符串 | `length` 字符串长度 |
|
||||||
|
|
||||||
|
```java
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.utils.processing.random.defaults;
|
||||||
|
|
||||||
|
int num = defaults.random(1, 100); // 生成 1~100 的随机整数
|
||||||
|
String str = defaults.randomString(16); // 生成 16 位随机字符串(大小写字母+数字)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 硬件标识生成器 (`hwid`)
|
||||||
|
|
||||||
|
组合 CPU、主板、MAC 地址、硬盘序列号等信息,通过 SHA-256 生成唯一的硬件标识符(HWID)。支持 Windows、macOS、Linux 及 Android 平台。
|
||||||
|
|
||||||
|
| 方法 | 说明 | 参数 |
|
||||||
|
|------------------------|----------|----|
|
||||||
|
| `getHWID.generateHWID()` | 生成硬件标识符 | 无 |
|
||||||
|
|
||||||
|
```java
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.utils.processing.hwid.getHWID;
|
||||||
|
|
||||||
|
String hwid = getHWID.generateHWID();
|
||||||
|
System.out.println("HWID: " + hwid);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. 版本信息 (`version`)
|
||||||
|
|
||||||
|
提供项目版本信息及编译时 Java/OpenJDK 版本常量。
|
||||||
|
|
||||||
|
| 方法 | 说明 |
|
||||||
|
|----------------------------|----------------|
|
||||||
|
| `version.GetVersion()` | 获取项目版本号 |
|
||||||
|
| `version.GetJavaVersion()` | 获取编译时 Java 版本 |
|
||||||
|
|
||||||
|
```java
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.version;
|
||||||
|
|
||||||
|
version v = new version();
|
||||||
|
System.out.println("项目版本: " + v.GetVersion());
|
||||||
|
System.out.println("Java版本: " + v.GetJavaVersion());
|
||||||
|
```
|
||||||
|
|
||||||
|
也可以通过统一入口调用:
|
||||||
|
|
||||||
|
```java
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.main;
|
||||||
|
|
||||||
|
main.version.getVersion(); // 项目版本
|
||||||
|
main.version.getJavaVersion(); // Java 版本
|
||||||
|
main.version.getOpenJDKVersion(); // OpenJDK 版本
|
||||||
|
main.version.getOpenJDKRuntimeEnvironment(); // OpenJDK 运行时环境
|
||||||
|
main.version.getOpenJDK64BitServerVM(); // OpenJDK 64-Bit Server VM
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. 运行时信息 (`runtime`)
|
||||||
|
|
||||||
|
获取当前 Java 运行时环境信息,包括 JAR 路径、JVM 版本、位数等。
|
||||||
|
|
||||||
|
**运行环境 (`RunEnv`):**
|
||||||
|
|
||||||
|
| 方法 | 说明 |
|
||||||
|
|-------------------------------|------------------------------------------|
|
||||||
|
| `RunEnv.getJarPath()` | 获取当前运行的 JAR 路径 |
|
||||||
|
| `RunEnv.getTempDir()` | 获取系统临时目录路径 |
|
||||||
|
| `RunEnv.newTempDir()` | 在系统临时目录下新建时间戳子目录,返回路径;已存在则返回 `null` |
|
||||||
|
| `RunEnv.newJarThisTempDir()` | 在 JAR 所在目录下新建时间戳子目录,返回路径;已存在则返回 `null` |
|
||||||
|
|
||||||
|
**Java 运行时环境 (`JavaRunTimeEnv`):**
|
||||||
|
|
||||||
|
| 方法 | 说明 |
|
||||||
|
|----------------------------------------|---------------|
|
||||||
|
| `JavaRunTimeEnv.JavaVersion()` | Java 版本号 |
|
||||||
|
| `JavaRunTimeEnv.JavaRuntimeEnvironmentVersion()` | 运行时环境版本号 |
|
||||||
|
| `JavaRunTimeEnv.JavaVMVersion()` | 虚拟机版本号 |
|
||||||
|
| `JavaRunTimeEnv.JavaBits()` | JDK 位数(如 64) |
|
||||||
|
| `JavaRunTimeEnv.JavaVMName()` | 虚拟机名称 |
|
||||||
|
|
||||||
|
```java
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.utils.runtime.RunEnv;
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.utils.runtime.JavaRunTimeEnv;
|
||||||
|
|
||||||
|
System.out.println("JAR路径: " + RunEnv.getJarPath());
|
||||||
|
System.out.println("临时目录: " + RunEnv.getTempDir());
|
||||||
|
System.out.println("新建临时目录: " + RunEnv.newTempDir());
|
||||||
|
System.out.println("JAR目录临时子目录: " + RunEnv.newJarThisTempDir());
|
||||||
|
System.out.println("Java版本: " + JavaRunTimeEnv.JavaVersion());
|
||||||
|
System.out.println("JVM位数: " + JavaRunTimeEnv.JavaBits());
|
||||||
|
```
|
||||||
|
|
||||||
|
也可以通过统一入口调用:
|
||||||
|
|
||||||
|
```java
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.main;
|
||||||
|
|
||||||
|
main.runtime.getJarPath(); // JAR 路径
|
||||||
|
main.runtime.getJavaVersion(); // Java 版本
|
||||||
|
main.runtime.getJavaRuntimeEnvironmentVersion(); // 运行时环境版本
|
||||||
|
main.runtime.getJavaVMVersion(); // 虚拟机版本
|
||||||
|
main.runtime.getJavaBits(); // JDK 位数
|
||||||
|
main.runtime.getJavaVMName(); // 虚拟机名称
|
||||||
|
|
||||||
|
// runtime.runenv 子接口
|
||||||
|
main.runtime.runenv.getTempDir(); // 系统临时目录
|
||||||
|
main.runtime.runenv.newTempDir(); // 新建临时目录
|
||||||
|
main.runtime.runenv.newJarThisTempDir(); // JAR 目录下新建临时目录
|
||||||
|
main.runtime.runenv.getJarThisTempDir(); // 同 newJarThisTempDir
|
||||||
```
|
```
|
||||||
|
|
||||||
## 构建
|
## 构建
|
||||||
@@ -111,6 +308,30 @@ main.echo.ColorHexPrintln("自定义颜色", "31");
|
|||||||
mvn compile
|
mvn compile
|
||||||
```
|
```
|
||||||
|
|
||||||
|
或打包为 JAR:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mvn package
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用
|
||||||
|
|
||||||
|
编译成功后,将 `target/gnu-java-utils-library-1.3-SNAPSHOT.jar` 放入项目依赖中,或在 Releases 中下载最新版 JAR 包。
|
||||||
|
|
||||||
|
**pom.xml 引入本地依赖:**
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>top.gtb520.java.gnu</groupId>
|
||||||
|
<artifactId>gnu_java_utils_library</artifactId>
|
||||||
|
<version>1.3-SNAPSHOT</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${project.basedir}/lib/gnu_java_utils_library-1.3-SNAPSHOT.jar</systemPath>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
```
|
||||||
|
|
||||||
## 异常处理
|
## 异常处理
|
||||||
|
|
||||||
压缩/解压方法在以下情况会抛出 `IllegalArgumentException`:
|
压缩/解压方法在以下情况会抛出 `IllegalArgumentException`:
|
||||||
@@ -118,6 +339,12 @@ mvn compile
|
|||||||
- **压缩时**:源路径不存在
|
- **压缩时**:源路径不存在
|
||||||
- **解压时**:目标路径不是有效的目录
|
- **解压时**:目标路径不是有效的目录
|
||||||
|
|
||||||
|
随机数方法在以下情况会抛出 `IllegalArgumentException`:
|
||||||
|
|
||||||
|
- **起始值大于结束值时**
|
||||||
|
|
||||||
## 许可证
|
## 许可证
|
||||||
|
|
||||||
本项目仅供学习与个人使用。
|
Apache License 2.0
|
||||||
|
|
||||||
|
禁止商业用途
|
||||||
|
|||||||
8
pom.xml
8
pom.xml
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>top.gtb520.java.gnu</groupId>
|
<groupId>top.gtb520.java.gnu</groupId>
|
||||||
<artifactId>gnu_java_utils_library</artifactId>
|
<artifactId>gnu_java_utils_library</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.3-SNAPSHOT</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>25</maven.compiler.source>
|
<maven.compiler.source>25</maven.compiler.source>
|
||||||
@@ -20,6 +20,12 @@
|
|||||||
<artifactId>commons-compress</artifactId>
|
<artifactId>commons-compress</artifactId>
|
||||||
<version>1.28.0</version>
|
<version>1.28.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<version>5.13.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -37,5 +37,94 @@ public interface main {
|
|||||||
static void ColorHexPrintln(String Message, String ColorCode) {
|
static void ColorHexPrintln(String Message, String ColorCode) {
|
||||||
top.gtb520.java.gnu.java.utils.library.utils.print.echo.ColorHexPrintln(Message, 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 项目版本信息获取接口与方法
|
||||||
|
interface version {
|
||||||
|
static String getVersion() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.version.VERSION;
|
||||||
|
}
|
||||||
|
static String getJavaVersion() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.version.JAVA_VERSION;
|
||||||
|
}
|
||||||
|
static String getOpenJDKVersion() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.version.OpenJDK_VERSION;
|
||||||
|
}
|
||||||
|
static String getOpenJDKRuntimeEnvironment() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.version.OpenJDK_Runtime_Environment;
|
||||||
|
}
|
||||||
|
static String getOpenJDK64BitServerVM() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.version.OpenJDK_64Bit_Server_VM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行时信息获取接口与方法
|
||||||
|
interface runtime {
|
||||||
|
static String getJarPath() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.utils.runtime.RunEnv.getJarPath();
|
||||||
|
}
|
||||||
|
static String getJavaVersion() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.utils.runtime.JavaRunTimeEnv.JavaVersion();
|
||||||
|
}
|
||||||
|
static String getJavaRuntimeEnvironmentVersion() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.utils.runtime.JavaRunTimeEnv.JavaRuntimeEnvironmentVersion();
|
||||||
|
}
|
||||||
|
static String getJavaVMVersion() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.utils.runtime.JavaRunTimeEnv.JavaVMVersion();
|
||||||
|
}
|
||||||
|
static String getJavaBits() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.utils.runtime.JavaRunTimeEnv.JavaBits();
|
||||||
|
}
|
||||||
|
static String getJavaVMName() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.utils.runtime.JavaRunTimeEnv.JavaVMName();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运行时等相关方法与接口
|
||||||
|
interface runenv {
|
||||||
|
// 获取运行时临时目录
|
||||||
|
static String newJarThisTempDir() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.utils.runtime.RunEnv.newJarThisTempDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新建临时目录
|
||||||
|
static String newTempDir() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.utils.runtime.RunEnv.newTempDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取临时目录
|
||||||
|
static String getTempDir() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.utils.runtime.RunEnv.getTempDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前运行的JAR文件路径
|
||||||
|
static String getJarThisTempDir() {
|
||||||
|
return top.gtb520.java.gnu.java.utils.library.utils.runtime.RunEnv.newJarThisTempDir();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package top.gtb520.java.gnu.java.utils.library.utils.print;
|
package top.gtb520.java.gnu.java.utils.library.utils.print;
|
||||||
|
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 终端彩色输出工具类
|
* 终端彩色输出工具类
|
||||||
* 提供基于 ANSI 转义序列的终端彩色打印功能
|
* 提供基于 ANSI 转义序列的终端彩色打印功能
|
||||||
@@ -8,13 +10,35 @@ public class echo {
|
|||||||
// 终端彩色打印
|
// 终端彩色打印
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用自定义十六进制颜色码在终端打印彩色文本
|
* 使用自定义颜色码在终端打印彩色文本
|
||||||
|
* 支持三种格式:
|
||||||
|
* - "#RRGGBB" 十六进制颜色(如 "#FFC0CB")
|
||||||
|
* - ANSI 颜色代码(如 "31" 表示红色)
|
||||||
|
* - ANSI 扩展色(如 "38;5;208" 表示扩展色)
|
||||||
*
|
*
|
||||||
* @param Message 要打印的文本内容
|
* @param Message 要打印的文本内容
|
||||||
* @param HexColor ANSI 颜色代码(如 "31" 表示红色,"38;5;208" 表示扩展色)
|
* @param HexColor 颜色代码,支持 "#RRGGBB"、ANSI 颜色代码或扩展色
|
||||||
*/
|
*/
|
||||||
public static void ColorHexPrintln(String Message, String HexColor) {
|
public static void ColorHexPrintln(String Message, String HexColor) {
|
||||||
System.out.println("\033[" + HexColor + "m" + Message + "\033[0m");
|
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);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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() + "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package top.gtb520.java.gnu.java.utils.library.utils.runtime;
|
||||||
|
|
||||||
|
// 运行时Java环境信息
|
||||||
|
public class JavaRunTimeEnv {
|
||||||
|
|
||||||
|
// Java版本号
|
||||||
|
public static String JavaVersion() {
|
||||||
|
return System.getProperty("java.version");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Java运行时环境版本号
|
||||||
|
public static String JavaRuntimeEnvironmentVersion() {
|
||||||
|
return System.getProperty("java.runtime.version");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取虚拟机版本
|
||||||
|
public static String JavaVMVersion() {
|
||||||
|
return System.getProperty("java.vm.version");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取 JDK 位数,64 位通常包含 amd64 或 64
|
||||||
|
public static String JavaBits() {
|
||||||
|
return System.getProperty("sun.arch.data.model");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取JavaVM名称
|
||||||
|
public static String JavaVMName() {
|
||||||
|
return System.getProperty("java.vm.name");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package top.gtb520.java.gnu.java.utils.library.utils.runtime;
|
||||||
|
|
||||||
|
import top.gtb520.java.gnu.java.utils.library.main;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
// 获取运行时的信息
|
||||||
|
public class RunEnv {
|
||||||
|
// 获取当前运行的JAR文件路径
|
||||||
|
public static String getJarPath() {
|
||||||
|
String path = main.class.getProtectionDomain().getCodeSource().getLocation().getPath();
|
||||||
|
if (System.getProperty("os.name").startsWith("Windows")) {
|
||||||
|
path = path.replace('/', '\\');
|
||||||
|
//去除路径最前面的 "\\"
|
||||||
|
path = path.substring(1);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取临时目录
|
||||||
|
public static String getTempDir() {
|
||||||
|
return System.getProperty("java.io.tmpdir");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新建临时目录,失败时返回 null
|
||||||
|
public static String newTempDir() {
|
||||||
|
return createTempDir(Path.of(getTempDir()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在 当前运行的JAR文件路径 下 新建临时目录,失败时返回 null
|
||||||
|
public static String newJarThisTempDir() {
|
||||||
|
Path parent = Path.of(getJarPath()).getParent();
|
||||||
|
if (parent == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return createTempDir(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在指定目录下创建以时间戳命名的临时目录,返回目录路径;目录已存在时返回 null
|
||||||
|
private static String createTempDir(Path parent) {
|
||||||
|
Path tempDir = parent.resolve(String.valueOf(System.currentTimeMillis()));
|
||||||
|
if (!tempDir.toFile().exists()) {
|
||||||
|
try {
|
||||||
|
tempDir.toFile().mkdirs();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return tempDir.toString();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package top.gtb520.java.gnu.java.utils.library;
|
||||||
|
|
||||||
|
public class version {
|
||||||
|
// 项目的版本信息,不代表实时运行环境
|
||||||
|
public static final String VERSION = "1.3";
|
||||||
|
public static final String JAVA_VERSION = "25";
|
||||||
|
public static final String OpenJDK_VERSION = "25.0.0.0.1";
|
||||||
|
public static final String OpenJDK_Runtime_Environment = "25.0.0.0.1+36-GA";
|
||||||
|
public static final String OpenJDK_64Bit_Server_VM = "25.0.0.0.1+36-GA";
|
||||||
|
|
||||||
|
public String GetVersion() {
|
||||||
|
return VERSION;
|
||||||
|
}
|
||||||
|
public String GetJavaVersion() {
|
||||||
|
return JAVA_VERSION;
|
||||||
|
}
|
||||||
|
public String GetOpenJDKVersion() {
|
||||||
|
return OpenJDK_VERSION;
|
||||||
|
}
|
||||||
|
public String GetOpenJDKRuntimeEnvironment() {
|
||||||
|
return OpenJDK_Runtime_Environment;
|
||||||
|
}
|
||||||
|
public String GetOpenJDK64BitServerVM() {
|
||||||
|
return OpenJDK_64Bit_Server_VM;
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/test/java/ColorPrintlnPlusTest2.java
Normal file
7
src/test/java/ColorPrintlnPlusTest2.java
Normal 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!");
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/test/java/HwidTest.java
Normal file
16
src/test/java/HwidTest.java
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,5 +9,16 @@ public class echo {
|
|||||||
main.echo.Println("PURPLE", ColorNameEnum.PURPLE);
|
main.echo.Println("PURPLE", ColorNameEnum.PURPLE);
|
||||||
main.echo.Println("GREEN", ColorNameEnum.GREEN);
|
main.echo.Println("GREEN", ColorNameEnum.GREEN);
|
||||||
main.echo.Println("RED", ColorNameEnum.RED);
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
src/test/java/echoTest.java
Normal file
32
src/test/java/echoTest.java
Normal 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 测试完成 ==========");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package top.gtb520.java.gnu.java.utils.library.utils.runtime;
|
||||||
|
|
||||||
|
import static top.gtb520.java.gnu.java.utils.library.utils.runtime.RunEnv.*;
|
||||||
|
|
||||||
|
class RunEnvTest {
|
||||||
|
public static void main() {
|
||||||
|
System.out.println(getJarPath());
|
||||||
|
System.out.printf(newJarThisTempDir() + "\n");
|
||||||
|
System.out.println(newTempDir());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user