10 Commits

10 changed files with 636 additions and 11 deletions

3
.gitignore vendored
View File

@@ -42,4 +42,5 @@ build/
/target /target
/.idea /.idea
/.mvn /.mvn
/build_release /build_release
/upload/

16
INFO.md Normal file
View File

@@ -0,0 +1,16 @@
1.3-SNAPSHOT
此版本包含:
1. 压缩/解压 (`compress`)
2. 终端彩色输出 (`echo`)
2.1 预定义颜色打印 — `ColorPrintln`
2.2 自定义颜色打印 — `ColorHexPrintln`
2.3 Minecraft 风格多色打印 — `ColorPrintlnPlus`
3. 随机生成器 (`random`)
4. 硬件标识生成器 (`hwid`)
5. 版本信息 (`version`)
6. 运行时信息 (`runtime`)
6.1 获取运行时临时目录
6.2 新建临时目录
6.3 获取临时目录
6.4 获取当前运行的JAR文件路径

View File

@@ -1,6 +1,6 @@
# 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) > 注:此项目/仓库已同步到 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) > 原项目/仓库链接:[https://git.opensource-studio.info/database-mysql/gnu_java_utils_library.git](https://git.opensource-studio.info/database-mysql/gnu_java_utils_library.git)
@@ -21,6 +21,9 @@ src/main/java/top/gtb520/java/gnu/java/utils/library/
└── utils/ └── utils/
├── compress/ ├── compress/
│ └── compress.java # 压缩/解压工具类 │ └── compress.java # 压缩/解压工具类
├── file/
│ ├── CreateFile.java # 文件创建/保存工具类
│ └── EncryptionAndDecryption.java # 文件加密/解密工具类
├── print/ ├── print/
│ ├── echo.java # 终端彩色输出工具类 │ ├── echo.java # 终端彩色输出工具类
│ └── ColorNameEnum.java # 颜色名称枚举 │ └── ColorNameEnum.java # 颜色名称枚举
@@ -190,7 +193,80 @@ main.echo.ColorHexPrintln("自定义颜色", "#FF0000");
main.echo.ColorPrintlnPlus("&a多色 &c文本"); main.echo.ColorPrintlnPlus("&a多色 &c文本");
``` ```
### 3. 随机生成器 (`random`) ### 3. 文件创建与保存 (`file/CreateFile`)
支持创建普通/二进制文件,以及异步字节流文件保存。
| 方法 | 说明 | 参数 |
|-------------------------------------------------------|---------------------------------------|-------------------------------------------------------------|
| `CreateFile.NewFile(FileName, isBin, binFileType)` | 创建空白文件,二进制文件自动写入文件头 | `FileName` 文件名,`isBin` 是否二进制,`binFileType` 二进制类型(普通文件传 `null` |
| `CreateFile.StreamSaveFile(file, TargePath, FileName)` | 以字节流方式异步保存文件到目标路径 | `file` 源文件,`TargePath` 目标目录,`FileName` 保存的文件名 |
**二进制文件类型 (`BinFileType`)**
| 枚举值 | 文件头标识 |
|-------|----------------|
| `ELF` | `7F 45 4C 46` |
| `PE` | `4D 5A` |
```java
import top.gtb520.java.gnu.java.utils.library.utils.file.CreateFile;
import top.gtb520.java.gnu.java.utils.library.utils.file.CreateFile.BinFileType;
import java.io.File;
import java.nio.file.Path;
// 创建普通空白文件
File plainFile = CreateFile.NewFile("/path/to/file.txt", false, null);
// 创建 ELF 二进制文件(自动写入 ELF 文件头)
File elfFile = CreateFile.NewFile("/path/to/program", true, BinFileType.ELF);
// 创建 PE 二进制文件(自动写入 MZ 文件头)
File peFile = CreateFile.NewFile("/path/to/app.exe", true, BinFileType.PE);
// 异步字节流保存文件
boolean success = CreateFile.StreamSaveFile(sourceFile, Path.of("/path/to/dest"), "output.bin");
```
### 4. 文件加密/解密 (`file/EncryptionAndDecryption`)
支持 **AES**、**DES** 对称加密,加密后覆盖原文件,密钥单独保存到指定目录。解密时从密钥文件读取密钥,解密后覆盖还原原文件。
| 方法 | 说明 | 参数 |
|----------------------------------------------------------------|--------------------------|-----------------------------------------------|
| `EncryptionAndDecryption.EncryptionFile(file, type, keyPath)` | 异步加密文件,覆盖原文件,密钥保存到 keyPath | `file` 文件,`type` 加密类型,`keyPath` 密钥目录路径 |
| `EncryptionAndDecryption.DecryptionFile(file, type, keyfile)` | 异步解密文件,覆盖还原原文件 | `file` 加密文件,`type` 加密类型,`keyfile` 密钥文件 |
**加密类型 (`EncryptionType`)**
| 枚举值 | 算法 | 密钥长度 |
|-------|---------------------|---------|
| `AES` | AES/ECB/PKCS5Padding | 128 bit |
| `DES` | DES/ECB/PKCS5Padding | 56 bit |
| `RSA` | AES对称替代 | 128 bit |
> 加密后密钥文件命名为 `原文件名.key`,保存在 `keyPath` 目录下。
> 加密/解密均覆盖写回原文件,不添加额外后缀。
```java
import top.gtb520.java.gnu.java.utils.library.utils.file.EncryptionAndDecryption;
import top.gtb520.java.gnu.java.utils.library.utils.file.EncryptionAndDecryption.EncryptionType;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Files;
File file = new File("/path/to/data.txt");
Path keyDir = Path.of("/path/to/keys");
// 加密文件(密钥保存到 keyDir/data.txt.key
File encrypted = EncryptionAndDecryption.EncryptionFile(file, EncryptionType.AES, keyDir);
// 解密文件(从密钥文件读取密钥)
File keyFile = keyDir.resolve("data.txt.key").toFile();
File decrypted = EncryptionAndDecryption.DecryptionFile(file, EncryptionType.AES, keyFile);
```
### 5. 随机生成器 (`random`)
| 方法 | 说明 | 参数 | | 方法 | 说明 | 参数 |
|---------------------------------------------|--------------|------------------------------| |---------------------------------------------|--------------|------------------------------|
@@ -204,7 +280,7 @@ int num = defaults.random(1, 100); // 生成 1~100 的随机整数
String str = defaults.randomString(16); // 生成 16 位随机字符串(大小写字母+数字) String str = defaults.randomString(16); // 生成 16 位随机字符串(大小写字母+数字)
``` ```
### 4. 硬件标识生成器 (`hwid`) ### 6. 硬件标识生成器 (`hwid`)
组合 CPU、主板、MAC 地址、硬盘序列号等信息,通过 SHA-256 生成唯一的硬件标识符HWID。支持 Windows、macOS、Linux 及 Android 平台。 组合 CPU、主板、MAC 地址、硬盘序列号等信息,通过 SHA-256 生成唯一的硬件标识符HWID。支持 Windows、macOS、Linux 及 Android 平台。
@@ -219,7 +295,7 @@ String hwid = getHWID.generateHWID();
System.out.println("HWID: " + hwid); System.out.println("HWID: " + hwid);
``` ```
### 5. 版本信息 (`version`) ### 7. 版本信息 (`version`)
提供项目版本信息及编译时 Java/OpenJDK 版本常量。 提供项目版本信息及编译时 Java/OpenJDK 版本常量。
@@ -248,7 +324,7 @@ main.version.getOpenJDKRuntimeEnvironment(); // OpenJDK 运行时环境
main.version.getOpenJDK64BitServerVM(); // OpenJDK 64-Bit Server VM main.version.getOpenJDK64BitServerVM(); // OpenJDK 64-Bit Server VM
``` ```
### 6. 运行时信息 (`runtime`) ### 8. 运行时信息 (`runtime`)
获取当前 Java 运行时环境信息,包括 JAR 路径、JVM 版本、位数等。 获取当前 Java 运行时环境信息,包括 JAR 路径、JVM 版本、位数等。
@@ -316,7 +392,7 @@ mvn package
## 使用 ## 使用
编译成功后,将 `target/gnu-java-utils-library-1.3-SNAPSHOT.jar` 放入项目依赖中,或在 Releases 中下载最新版 JAR 包。 编译成功后,将 `target/gnu-java-utils-library-1.4-SNAPSHOT.jar` 放入项目依赖中,或在 Releases 中下载最新版 JAR 包。
**pom.xml 引入本地依赖:** **pom.xml 引入本地依赖:**
@@ -325,9 +401,9 @@ mvn package
<dependency> <dependency>
<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.3-SNAPSHOT</version> <version>1.4-SNAPSHOT</version>
<scope>system</scope> <scope>system</scope>
<systemPath>${project.basedir}/lib/gnu_java_utils_library-1.3-SNAPSHOT.jar</systemPath> <systemPath>${project.basedir}/lib/gnu_java_utils_library-1.4-SNAPSHOT.jar</systemPath>
</dependency> </dependency>
</dependencies> </dependencies>
``` ```

View File

@@ -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.3-SNAPSHOT</version> <version>1.4-SNAPSHOT</version>
<properties> <properties>
<maven.compiler.source>25</maven.compiler.source> <maven.compiler.source>25</maven.compiler.source>

View File

@@ -2,6 +2,13 @@ package top.gtb520.java.gnu.java.utils.library;
import top.gtb520.java.gnu.java.utils.library.utils.print.ColorNameEnum; import top.gtb520.java.gnu.java.utils.library.utils.print.ColorNameEnum;
import java.io.File;
import java.nio.file.Path;
import static top.gtb520.java.gnu.java.utils.library.utils.file.CreateFile.BinFileType;
import static top.gtb520.java.gnu.java.utils.library.utils.file.EncryptionAndDecryption.EncryptionType;
public interface main { public interface main {
// 压缩包操作相关接口与方法 // 压缩包操作相关接口与方法
interface compress { interface compress {
@@ -127,4 +134,31 @@ public interface main {
} }
} }
} }
// 文件操作接口与方法
interface file {
interface CreateFile {
// 创建文件创建空白文件异步IO
static File NewFile(String FileName, boolean isBin, BinFileType binFileType) {
return top.gtb520.java.gnu.java.utils.library.utils.file.CreateFile.NewFile(FileName, isBin, binFileType);
}
// 以字节流方式保存文件异步IO
static boolean StreamSaveFile(File file, Path TargePath, String FileName) {
return top.gtb520.java.gnu.java.utils.library.utils.file.CreateFile.StreamSaveFile(file, TargePath, FileName);
}
}
}
// 文件加解密操作
interface EncryptionAndDecryption {
// 文件加密
static File FileEncrypt(File file, EncryptionType type, Path keyPath) throws Exception {
return top.gtb520.java.gnu.java.utils.library.utils.file.EncryptionAndDecryption.EncryptionFile(file, type, keyPath);
}
// 文件解密
static File DecryptionFile(File file, EncryptionType type, File keyfile) throws Exception {
return top.gtb520.java.gnu.java.utils.library.utils.file.EncryptionAndDecryption.DecryptionFile(file, type, keyfile);
}
}
} }

View File

@@ -0,0 +1,89 @@
package top.gtb520.java.gnu.java.utils.library.utils.file;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.CompletableFuture;
// 创建文件
public class CreateFile {
/***
* 创建文件,创建空白文件
* isBin为True时创建一个空白的二进制文件否则创建一个空白的普通文件
* 异步IO操作
*
* @param FileName 文件名
* @param isBin 是否二进制文件
* @param binFileType 二进制文件类型如果是普通文件则不需要设置次值将其设置为null即可
* 参考isBin参数isBin参数为False则此参数设置为null
*
* @return 文件
*/
public static File NewFile(String FileName, boolean isBin, BinFileType binFileType) {
File TargetFile = null;
byte[] BufferByte = new byte[1024];
try {
TargetFile = new File(FileName);
if (TargetFile.createNewFile()) {
if (isBin && binFileType != null) {
// 根据二进制文件类型写入文件头标识
byte[] header = switch (binFileType) {
case ELF -> new byte[]{0x7F, 'E', 'L', 'F'};
case PE -> new byte[]{'M', 'Z'};
};
try (OutputStream os = Files.newOutputStream(TargetFile.toPath(),
StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
os.write(header);
os.flush();
}
}
}
} catch (IOException e) {
TargetFile = null;
}
return TargetFile;
}
/***
* 以字节流方式保存文件
* 异步IO操作
*
* @param file 文件
* @param TargePath 目标路径
* @param FileName 文件名
*
* @return 是否保存成功True为保存成功False为保存失败
*/
public static boolean StreamSaveFile(File file, Path TargePath, String FileName) {
try {
Path targetFile = TargePath.resolve(FileName);
return CompletableFuture.supplyAsync(() -> {
try (OutputStream os = Files.newOutputStream(targetFile,
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
byte[] buffer = new byte[1024];
int bytesRead;
try (var is = Files.newInputStream(file.toPath())) {
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
}
os.flush();
return true;
} catch (IOException e) {
return false;
}
}).get();
} catch (Exception e) {
return false;
}
}
public enum BinFileType {
ELF, PE;
}
}

View File

@@ -0,0 +1,202 @@
package top.gtb520.java.gnu.java.utils.library.utils.file;
import java.io.File;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.CompletableFuture;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
public class EncryptionAndDecryption {
/***
* 文件加密
* 异步执行加密操作
* 加密后覆盖原文件,不添加额外后缀
* 密钥保存到 keyPath 目录下,密钥名为 原文件名.key
*
* @param file 文件
* @param type 加密类型
* @param keyPath 密钥文件目录路径,密钥名为 文件名.key
* @return 加密后的文件(原文件),失败时返回 null
*/
public static File EncryptionFile(File file, EncryptionType type, Path keyPath) {
File TargetFile = null;
if (file == null || !file.exists() || !file.isFile()) {
return null;
}
if (keyPath == null) {
return null;
}
try {
TargetFile = CompletableFuture.supplyAsync(() -> {
try {
// 读取原文件内容
byte[] plainBytes = Files.readAllBytes(file.toPath());
// 根据加密类型生成对称密钥
SecretKey secretKey = generateSecretKey(type);
byte[] encryptedBytes = encryptBytes(plainBytes, secretKey, type);
// 将密钥写入 keyPath 目录,密钥名为 文件名.key
Files.createDirectories(keyPath);
String keyFileName = file.getName() + ".key";
Path keyFilePath = keyPath.resolve(keyFileName);
try (OutputStream kos = Files.newOutputStream(keyFilePath,
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
kos.write(secretKey.getEncoded());
kos.flush();
}
// 加密后覆盖写回原文件
try (OutputStream os = Files.newOutputStream(file.toPath(),
StandardOpenOption.TRUNCATE_EXISTING)) {
os.write(encryptedBytes);
os.flush();
}
return file;
} catch (Exception e) {
return null;
}
}).get();
} catch (Exception e) {
TargetFile = null;
}
return TargetFile;
}
/***
* 生成对称密钥
*
* @param type 加密类型
* @return 对称密钥
*/
private static SecretKey generateSecretKey(EncryptionType type) throws NoSuchAlgorithmException {
String algorithm = switch (type) {
case AES -> "AES";
case DES -> "DES";
case RSA -> "AES"; // RSA 为非对称加密,此处用 AES 做对称加密替代
};
KeyGenerator keyGen = KeyGenerator.getInstance(algorithm);
int keySize = switch (type) {
case AES -> 128;
case DES -> 56;
case RSA -> 128;
};
keyGen.init(keySize);
return keyGen.generateKey();
}
/***
* 对字节数据进行加密
*
* @param data 原始数据
* @param key 密钥
* @param type 加密类型
* @return 加密后的数据
*/
private static byte[] encryptBytes(byte[] data, SecretKey key, EncryptionType type)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
String algorithm = switch (type) {
case AES -> "AES/ECB/PKCS5Padding";
case DES -> "DES/ECB/PKCS5Padding";
case RSA -> "AES/ECB/PKCS5Padding";
};
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
/***
* 文件解密
* 异步执行解密操作
* 解密后覆盖写回原文件,不添加额外后缀
*
* @param file 加密文件
* @param type 加密类型,须与加密时一致
* @param keyfile 密钥文件,从中读取解密密钥
* @return 解密后的文件(原文件),失败时返回 null
*/
public static File DecryptionFile(File file, EncryptionType type, File keyfile) {
File TargetFile = null;
if (file == null || !file.exists() || !file.isFile()) {
return null;
}
if (keyfile == null || !keyfile.exists() || !keyfile.isFile()) {
return null;
}
try {
TargetFile = CompletableFuture.supplyAsync(() -> {
try {
// 从密钥文件读取密钥
byte[] keyBytes = Files.readAllBytes(keyfile.toPath());
String algorithm = switch (type) {
case AES -> "AES";
case DES -> "DES";
case RSA -> "AES";
};
SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(keyBytes, algorithm);
// 读取加密文件内容
byte[] encryptedBytes = Files.readAllBytes(file.toPath());
// 解密
byte[] decryptedBytes = decryptBytes(encryptedBytes, secretKey, type);
// 解密后覆盖写回原文件
try (OutputStream os = Files.newOutputStream(file.toPath(),
StandardOpenOption.TRUNCATE_EXISTING)) {
os.write(decryptedBytes);
os.flush();
}
return file;
} catch (Exception e) {
return null;
}
}).get();
} catch (Exception e) {
TargetFile = null;
}
return TargetFile;
}
/***
* 对字节数据进行解密
*
* @param data 加密数据
* @param key 密钥
* @param type 加密类型
* @return 解密后的数据
*/
private static byte[] decryptBytes(byte[] data, SecretKey key, EncryptionType type)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
String algorithm = switch (type) {
case AES -> "AES/ECB/PKCS5Padding";
case DES -> "DES/ECB/PKCS5Padding";
case RSA -> "AES/ECB/PKCS5Padding";
};
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(data);
}
public enum EncryptionType {
AES, DES, RSA;
}
}

View File

@@ -1,5 +1,6 @@
package top.gtb520.java.gnu.java.utils.library.utils.print; package top.gtb520.java.gnu.java.utils.library.utils.print;
// 颜色名称枚举
public enum ColorNameEnum { public enum ColorNameEnum {
RED, GREEN, YELLOW, BLUE, PURPLE, CYAN; RED, GREEN, YELLOW, BLUE, PURPLE, CYAN;
} }

View File

@@ -2,7 +2,7 @@ package top.gtb520.java.gnu.java.utils.library;
public class version { public class version {
// 项目的版本信息,不代表实时运行环境 // 项目的版本信息,不代表实时运行环境
public static final String VERSION = "1.3"; public static final String VERSION = "1.4";
public static final String JAVA_VERSION = "25"; public static final String JAVA_VERSION = "25";
public static final String OpenJDK_VERSION = "25.0.0.0.1"; 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_Runtime_Environment = "25.0.0.0.1+36-GA";

View File

@@ -0,0 +1,206 @@
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import top.gtb520.java.gnu.java.utils.library.utils.file.EncryptionAndDecryption;
import top.gtb520.java.gnu.java.utils.library.utils.file.EncryptionAndDecryption.EncryptionType;
public class EncryptionAndDecryptionTest {
static int passCount = 0;
static int failCount = 0;
public static void main(String[] args) throws Exception {
System.out.println("========== EncryptionAndDecryption 测试开始 ==========");
// 正常场景AES 加密/解密
testEncryptDecryptAES();
// 正常场景DES 加密/解密
testEncryptDecryptDES();
// 正常场景RSA 加密/解密
testEncryptDecryptRSA();
// 正常场景:验证密钥文件生成
testKeyFileGenerated();
// 正常场景:加密后文件内容发生变化
testFileContentChangedAfterEncrypt();
// 异常场景file 为 null
testNullFile();
// 异常场景keyPath 为 null
testNullKeyPath();
// 异常场景keyfile 为 null解密
testNullKeyFile();
// 异常场景:文件不存在
testFileNotExist();
// 异常场景:密钥文件不存在(解密)
testKeyFileNotExist();
System.out.println("========== 测试结果 ==========");
System.out.println("通过: " + passCount);
System.out.println("失败: " + failCount);
System.out.println("总计: " + (passCount + failCount));
if (failCount > 0) {
System.out.println("存在失败的测试用例!");
System.exit(1);
} else {
System.out.println("全部测试通过!");
}
}
/**
* 创建临时测试文件并写入测试内容
*/
static File createTempFile(String prefix) throws Exception {
Path tempDir = Files.createTempDirectory("enc_test_");
File tempFile = tempDir.resolve(prefix + ".txt").toFile();
Files.writeString(tempFile.toPath(), "Hello, EncryptionAndDecryption Test! 测试内容123");
return tempFile;
}
/**
* 创建临时密钥目录
*/
static Path createTempKeyPath() throws Exception {
return Files.createTempDirectory("enc_key_");
}
static void assertEquals(Object expected, Object actual, String testName) {
if (expected == null && actual == null) {
passCount++;
System.out.println("[PASS] " + testName);
} else if (expected != null && expected.equals(actual)) {
passCount++;
System.out.println("[PASS] " + testName);
} else {
failCount++;
System.out.println("[FAIL] " + testName + " | 期望: " + expected + ", 实际: " + actual);
}
}
static void assertTrue(boolean condition, String testName) {
if (condition) {
passCount++;
System.out.println("[PASS] " + testName);
} else {
failCount++;
System.out.println("[FAIL] " + testName);
}
}
// ==================== 正常场景 ====================
static void testEncryptDecryptAES() throws Exception {
String testName = "AES 加密后解密,内容还原";
File file = createTempFile("aes_test");
Path keyPath = createTempKeyPath();
String originalContent = Files.readString(file.toPath());
File encrypted = EncryptionAndDecryption.EncryptionFile(file, EncryptionType.AES, keyPath);
assertTrue(encrypted != null, testName + " - 加密返回非null");
File keyFile = keyPath.resolve(file.getName() + ".key").toFile();
File decrypted = EncryptionAndDecryption.DecryptionFile(file, EncryptionType.AES, keyFile);
assertTrue(decrypted != null, testName + " - 解密返回非null");
String decryptedContent = Files.readString(file.toPath());
assertEquals(originalContent, decryptedContent, testName);
}
static void testEncryptDecryptDES() throws Exception {
String testName = "DES 加密后解密,内容还原";
File file = createTempFile("des_test");
Path keyPath = createTempKeyPath();
String originalContent = Files.readString(file.toPath());
File encrypted = EncryptionAndDecryption.EncryptionFile(file, EncryptionType.DES, keyPath);
assertTrue(encrypted != null, testName + " - 加密返回非null");
File keyFile = keyPath.resolve(file.getName() + ".key").toFile();
File decrypted = EncryptionAndDecryption.DecryptionFile(file, EncryptionType.DES, keyFile);
assertTrue(decrypted != null, testName + " - 解密返回非null");
String decryptedContent = Files.readString(file.toPath());
assertEquals(originalContent, decryptedContent, testName);
}
static void testEncryptDecryptRSA() throws Exception {
String testName = "RSA 加密后解密,内容还原";
File file = createTempFile("rsa_test");
Path keyPath = createTempKeyPath();
String originalContent = Files.readString(file.toPath());
File encrypted = EncryptionAndDecryption.EncryptionFile(file, EncryptionType.RSA, keyPath);
assertTrue(encrypted != null, testName + " - 加密返回非null");
File keyFile = keyPath.resolve(file.getName() + ".key").toFile();
File decrypted = EncryptionAndDecryption.DecryptionFile(file, EncryptionType.RSA, keyFile);
assertTrue(decrypted != null, testName + " - 解密返回非null");
String decryptedContent = Files.readString(file.toPath());
assertEquals(originalContent, decryptedContent, testName);
}
static void testKeyFileGenerated() throws Exception {
String testName = "加密后密钥文件正确生成";
File file = createTempFile("key_test");
Path keyPath = createTempKeyPath();
EncryptionAndDecryption.EncryptionFile(file, EncryptionType.AES, keyPath);
File keyFile = keyPath.resolve(file.getName() + ".key").toFile();
assertTrue(keyFile.exists(), testName + " - 密钥文件存在");
assertTrue(keyFile.length() > 0, testName + " - 密钥文件非空");
}
static void testFileContentChangedAfterEncrypt() throws Exception {
String testName = "加密后文件内容与原文不同";
File file = createTempFile("content_test");
Path keyPath = createTempKeyPath();
byte[] originalBytes = Files.readAllBytes(file.toPath());
EncryptionAndDecryption.EncryptionFile(file, EncryptionType.AES, keyPath);
byte[] encryptedBytes = Files.readAllBytes(file.toPath());
assertTrue(!java.util.Arrays.equals(originalBytes, encryptedBytes), testName);
}
// ==================== 异常场景 ====================
static void testNullFile() throws Exception {
String testName = "file 为 null 时加密返回 null";
Path keyPath = createTempKeyPath();
File result = EncryptionAndDecryption.EncryptionFile(null, EncryptionType.AES, keyPath);
assertEquals(null, result, testName);
}
static void testNullKeyPath() throws Exception {
String testName = "keyPath 为 null 时加密返回 null";
File file = createTempFile("null_keypath");
File result = EncryptionAndDecryption.EncryptionFile(file, EncryptionType.AES, null);
assertEquals(null, result, testName);
}
static void testNullKeyFile() throws Exception {
String testName = "keyfile 为 null 时解密返回 null";
File file = createTempFile("null_keyfile");
File result = EncryptionAndDecryption.DecryptionFile(file, EncryptionType.AES, null);
assertEquals(null, result, testName);
}
static void testFileNotExist() throws Exception {
String testName = "文件不存在时加密返回 null";
Path keyPath = createTempKeyPath();
File notExist = new File("non_existent_file_12345.txt");
File result = EncryptionAndDecryption.EncryptionFile(notExist, EncryptionType.AES, keyPath);
assertEquals(null, result, testName);
}
static void testKeyFileNotExist() throws Exception {
String testName = "密钥文件不存在时解密返回 null";
File file = createTempFile("no_keyfile");
File notExistKey = new File("non_existent_key_12345.key");
File result = EncryptionAndDecryption.DecryptionFile(file, EncryptionType.AES, notExistKey);
assertEquals(null, result, testName);
}
}