从java移动代码到kotlin
All checks were successful
Gitea Actions Build / Build (push) Successful in 5m39s

This commit is contained in:
Armamem0t 2025-09-12 17:12:32 +08:00
parent d12fbe0cce
commit 56080634c7
Signed by: minglipro
GPG Key ID: 5F355A77B22AA93B
16 changed files with 693 additions and 629 deletions

View File

@ -16,7 +16,7 @@
* ProjectName mingli-utils
* ModuleName mingli-utils
* CurrentFile build.gradle.kts
* LastUpdate 2025-09-10 11:08:55
* LastUpdate 2025-09-12 14:06:21
* UpdateUser MingLiPro
*/
@ -28,6 +28,8 @@ plugins {
java
id("java-library")
id("maven-publish")
kotlin("jvm") version "2.2.20"
id("org.jetbrains.dokka") version "2.0.0"
}
val GROUPSID = project.properties["GROUPSID"] as String
@ -41,24 +43,31 @@ base {
archivesName.set(ARTIFACTID)
}
val buildDir: java.nio.file.Path = File("build").toPath()
sourceSets {
main {
java {
srcDirs("src/main/java")
}
kotlin {
srcDirs("src/main/kotlin")
}
resources {
srcDirs("src/main/resources")
}
}
}
configurations {
}
java {
withJavadocJar()
withSourcesJar()
toolchain.languageVersion.set(JavaLanguageVersion.of(8))
}
dependencies {
annotationProcessor("org.jetbrains:annotations:24.0.0")
annotationProcessor("org.projectlombok:lombok:1.18.38")
@ -74,7 +83,6 @@ dependencies {
implementation("org.jetbrains:annotations:24.0.0")
implementation("net.java.dev.jna:jna:5.17.0")
implementation("jakarta.annotation:jakarta.annotation-api:2.1.1")
}
@ -82,6 +90,21 @@ tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
}
tasks.register<Jar>("javaDocJar") {
group = "build"
archiveClassifier.set("javadoc")
dependsOn(tasks.dokkaGfm, tasks.dokkaHtml, tasks.dokkaJavadoc, tasks.dokkaJekyll)
from(buildDir.resolve("dokka/javadoc"))
}
tasks.register<Jar>("kotlinDocJar") {
group = "build"
archiveClassifier.set("kotlindoc")
dependsOn(tasks.dokkaHtml)
from(buildDir.resolve("dokka/html"))
}
tasks.build {
dependsOn("javaDocJar", "kotlinDocJar")
}
tasks.withType<JavaExec>().configureEach {
jvmArgs = listOf(
"-Dfile.encoding=UTF-8",
@ -91,12 +114,6 @@ tasks.withType<JavaExec>().configureEach {
}
tasks.withType<Javadoc> {
options.encoding = "UTF-8"
}
tasks.withType<org.gradle.jvm.tasks.Jar> {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest {
@ -143,6 +160,19 @@ publishing {
groupId = GROUPSID
artifactId = ARTIFACTID
version = VERSIONS
artifact(tasks.named("javaDocJar"))
artifact(tasks.named("kotlinDocJar"))
pom {
name.set(project.name)
url.set("https://github.com/minglipro/mingli-utils")
licenses {
license {
name.set("Apache-2.0")
url.set("https://opensource.org/licenses/Apache-2.0")
}
}
}
}
}
}

View File

@ -16,10 +16,10 @@
# ProjectName mingli-utils
# ModuleName mingli-utils
# CurrentFile gradle.properties
# LastUpdate 2025-09-09 09:34:12
# LastUpdate 2025-09-12 14:10:24
# UpdateUser MingLiPro
#
JDKVERSIONS=1.8
GROUPSID=com.mingliqiye.utils
ARTIFACTID=mingli-utils
VERSIONS=3.2.6
VERSIONS=3.2.7

View File

@ -1,7 +0,0 @@
/**
*
* AES 加密
* @author MingLiPro
*
*/
package com.mingliqiye.utils.aes;

View File

@ -1,3 +1,25 @@
/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile Range.java
* LastUpdate 2025-09-12 17:12:29
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.iterator;
import lombok.Getter;
@ -7,7 +29,8 @@ import java.util.Iterator;
/**
* 范围 Range<br>
* 类似 KT的 {@code 0..10 = Range.of(0,10)}
* Iterable 可遍历对象<br>
* 类似 KT的 {@code 0..10 = Range.of(0,10)} {@code 0..10 step 2 = Range.of(0,10,2)}
* @author MingLiPro
* @since 3.2.6
*/
@ -16,6 +39,7 @@ public class Range implements Iterable<Integer> {
private final int start;
private final int end;
private final int step;
private int current;
/**
@ -27,8 +51,22 @@ public class Range implements Iterable<Integer> {
* @see Integer
*/
public Range(int start, int end) {
this(start, end, 1);
}
/**
* 创建一个范围 <br>
* 最大值{@code Integer.MAX_VALUE = 2147483647 } <br>
* 最小值{@code Integer.MIN_VALUE = -2147483648} <br>
* @param start 开始 (包含)
* @param end 完毕 (包含)
* @param step 步长
* @see Integer
*/
public Range(int start, int end, int step) {
this.start = start;
this.current = start;
this.step = step;
this.end = end + 1;
}
@ -68,6 +106,32 @@ public class Range implements Iterable<Integer> {
return new Range(start, end);
}
/**
* 创建一个范围 <br>
* 最大值{@code Integer.MAX_VALUE = 2147483647 } <br>
* 最小值{@code Integer.MIN_VALUE = -2147483648} <br>
* @param start 开始 (包含)
* @param end 完毕 (包含)
* @param step 步长
* @see Integer
*/
public static Range of(int start, int end, int step) {
return new Range(start, end, step);
}
/**
* 创建一个范围 <br>
* 最大值{@code Integer.MAX_VALUE = 2147483647 } <br>
* 最小值{@code Integer.MIN_VALUE = -2147483648} <br>
* @param start 开始 (包含)
* @param end 完毕 (包含)
* @param step 步长
* @see Integer
*/
public static Range range(int start, int end, int step) {
return new Range(start, end, step);
}
/**
* 创建一个范围 {@code 0 - range}<br>
* 最大值{@code Integer.MAX_VALUE = 2147483647 } <br>
@ -110,7 +174,12 @@ public class Range implements Iterable<Integer> {
if (current >= end) {
return null;
}
return current++;
try {
return current;
} finally {
current = current + step;
}
}
};
}

View File

@ -1,90 +0,0 @@
/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile RandomBytes.java
* LastUpdate 2025-09-09 08:37:34
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.random;
import com.mingliqiye.utils.collection.ForEach;
/**
* @author MingLiPro
*/
public class RandomBytes {
/**
* 生成指定长度的随机字节数组
* @param length 数组长度
* @return 包含随机字节的数组
*/
public static byte[] randomBytes(int length) {
byte[] bytes = new byte[length];
// 使用forEach遍历数组为每个位置生成随机字节
ForEach.forEach(bytes, (b, i) ->
bytes[i] = randomByte((byte) 0x00, (byte) 0xff)
);
return bytes;
}
/**
* 生成指定长度的随机字节数组
* 从给定的字节数组中随机选择字节来填充新数组
*
* @param length 要生成的随机字节数组的长度
* @param bytes 用于随机选择的源字节数组
* @return 包含随机字节的新数组
*/
public static byte[] randomBytes(int length, byte[] bytes) {
byte[] rbytes = new byte[length];
// 从源数组中随机选择字节填充到结果数组中
for (int i = 0; i < length; i++) {
rbytes[i] = bytes[RandomInt.randomInt(i, bytes.length - 1)];
}
return rbytes;
}
/**
* 生成指定范围内的随机字节
* @param from 起始字节值包含
* @param to 结束字节值包含
* @return 指定范围内的随机字节
*/
public static byte randomByte(byte from, byte to) {
// 将byte转换为int进行计算避免符号问题
int fromInt = from & 0xFF;
int toInt = to & 0xFF;
int randomValue = RandomInt.randomInt(fromInt, toInt);
return (byte) (randomValue & 0xFF);
}
/**
* 生成指定范围内的随机字节不包含边界值
* @param from 起始字节值不包含
* @param to 结束字节值不包含
* @return 指定范围内的随机字节
*/
public static byte randomByteNoHave(byte from, byte to) {
// 将byte转换为int进行计算避免符号问题
int fromInt = from & 0xFF;
int toInt = to & 0xFF;
int randomValue = RandomInt.randomIntNoHave(fromInt, toInt);
return (byte) (randomValue & 0xFF);
}
}

View File

@ -1,59 +0,0 @@
/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile RandomInt.java
* LastUpdate 2025-09-09 08:37:33
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.random;
import java.util.concurrent.ThreadLocalRandom;
/**
* @author MingLiPro
*/
public class RandomInt {
/**
* 生成指定范围内的随机整数
* @param min 最小值包含
* @param max 最大值不包含
* @return 随机整数
*/
public static int randomIntNoHave(int min, int max) {
if (min > max) {
int t = min;
min = max;
max = t;
}
if (min == max) {
return min;
}
return ThreadLocalRandom.current().nextInt(min, max);
}
/**
* 生成指定范围内的随机整数
* @param min 最小值包含
* @param max 最大值包含
* @return 随机整数
*/
public static int randomInt(int min, int max) {
return randomIntNoHave(min, ++max);
}
}

View File

@ -1,63 +0,0 @@
/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile RandomString.java
* LastUpdate 2025-09-09 08:37:33
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.random;
/**
* 随机字符串生成工具类
* 提供生成指定长度随机字符串的功能
*
* @author MingLiPro
*/
public class RandomString {
/**
* 生成指定长度和字符集的随机字符串
*
* @param length 要生成的随机字符串长度
* @param chars 用于生成随机字符串的字符集
* @return 指定长度的随机字符串
*/
public static String randomString(int length, String chars) {
String[] charsd = chars.split("");
StringBuilder sb = new StringBuilder(length);
// 循环生成随机字符并拼接
for (int i = 0; i < length; i++) {
int index = RandomInt.randomInt(0, charsd.length - 1);
sb.append(charsd[index]);
}
return sb.toString();
}
/**
* 生成指定长度的随机字符串使用默认字符集(数字+大小写字母)
*
* @param length 要生成的随机字符串长度
* @return 指定长度的随机字符串
*/
public static String randomString(int length) {
return randomString(
length,
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
);
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile Main.java
* LastUpdate 2025-09-12 12:19:48
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.test;
import com.mingliqiye.utils.version.VersionUtils;
public class Main {
public static void main(String[] args) {
System.out.println(VersionUtils.is("1.3", "1.2.3"));
}
}

View File

@ -1,285 +0,0 @@
/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile UUID.java
* LastUpdate 2025-09-10 11:14:27
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.uuid;
import com.github.f4b6a3.uuid.UuidCreator;
import com.mingliqiye.utils.string.StringUtil;
import com.mingliqiye.utils.time.DateTime;
import com.mingliqiye.utils.time.DateTimeOffset;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.time.temporal.ChronoUnit;
import java.util.Locale;
import java.util.Objects;
import lombok.Data;
/**
* UUID 工具类用于生成解析和操作 UUID
* 支持时间戳型 UUID版本1以及标准 UUID 的创建与转换
*
* @author MingLiPro
*/
@Data
public class UUID implements Serializable {
/**
* 内部封装的 java.util.UUID 实例
*/
private java.util.UUID uuid;
/**
* 构造一个由指定高位和低位组成的 UUID
*
* @param msb 高64位
* @param lsb 低64位
*/
public UUID(long msb, long lsb) {
uuid = new java.util.UUID(msb, lsb);
}
/**
* 构造一个基于当前时间的时间戳型 UUID版本1<br>
* 由于springboot 默认使用此构造函数构造UUID 导致致命BUG 废弃<br>
* 下个大版本删除<br>
* @deprecated 请使用 <code>UUID.getTimeBased()</code>
*/
@Deprecated
public UUID() {
uuid = UUID.getTimeBased().GetUUID();
}
/**
* 使用给定的 java.util.UUID 对象构造一个新的 UUID 实例
*
* @param uuid java.util.UUID 实例
*/
public UUID(java.util.UUID uuid) {
this.uuid = uuid;
}
/**
* 根据字符串表示的 UUID 构造一个新的 UUID 实例
*
* @param uuid 字符串形式的 UUID
*/
public UUID(String uuid) {
this.uuid = java.util.UUID.fromString(uuid);
}
/**
* 获取一个基于当前时间生成的时间戳型 UUID版本1
*
* @return 时间戳型 UUID
*/
public static UUID getTimeBased() {
return new UUID(UuidCreator.getTimeBased());
}
/**
* 将字节数组转换为 UUID 实例
*
* @param bytes 表示 UUID 16 字节数据
* @return 新建的 UUID 实例
*/
public static UUID of(byte[] bytes) {
if (bytes == null) {
return null;
}
ByteBuffer bb = ByteBuffer.wrap(bytes);
long msb = bb.getLong();
long lsb = bb.getLong();
return new UUID(msb, lsb);
}
/**
* 将字符串解析为 UUID 实例如果解析失败则抛出 UUIDException
*
* @param data UUID 字符串
* @return 解析后的 UUID 实例
* @throws UUIDException 如果解析失败
*/
public static UUID of(String data) {
if (data == null) {
return null;
}
try {
return new UUID(java.util.UUID.fromString(data));
} catch (Exception e) {
throw new UUIDException(e.getMessage(), e);
}
}
/**
* UUID 转换为 16 字节的字节数组
*
* @return 表示该 UUID 的字节数组
*/
public byte[] toBytes() {
if (this.uuid == null) {
return null;
}
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
return bb.array();
}
/**
* 获取内部封装的 java.util.UUID 实例
*
* @return java.util.UUID 实例
*/
public java.util.UUID GetUUID() {
return uuid;
}
/**
* UUID 转换为字符串表示默认使用小写格式
*
* @return UUID 字符串
*/
public String toUUIDString() {
return toUUIDString(false);
}
/**
* UUID 转换为字符串表示并可选择是否使用大写
*
* @param u 是否使用大写格式
* @return UUID 字符串
* @throws UUIDException 如果 uuid null
*/
public String toUUIDString(boolean u) {
if (uuid == null) {
throw new UUIDException("uuid is null : NullPointerException");
}
if (u) {
return uuid.toString().toUpperCase(Locale.ROOT);
}
return uuid.toString();
}
/**
* 计算此 UUID 的哈希码
*
* @return 哈希码值
*/
@Override
public int hashCode() {
return Objects.hash(uuid);
}
/**
* 判断两个 UUID 是否相等
*
* @param o 比较对象
* @return 如果相等返回 true否则返回 false
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
UUID uuid = (UUID) o;
return Objects.equals(this.uuid, uuid.uuid);
}
/**
* 返回此 UUID 的字符串表示包含版本信息和时间戳如果是版本1
*
* @return UUID 的详细字符串表示
*/
@Override
public String toString() {
if (uuid == null) {
return "UUID(null)";
}
return StringUtil.format(
"UUID(uuid={},version={})",
toUUIDString(true),
uuid.version()
);
}
/**
* 从时间戳型 UUID 中提取时间戳并转换为 DateTime 对象
*
* @return 对应的 DateTime 对象如果 uuid null则返回 null
*/
public DateTime getDateTime() {
if (uuid == null) {
return null;
}
if (uuid.version() != 1) {
return null;
}
return DateTime.of(uuid.timestamp() / 10_000).add(
DateTimeOffset.of(-141427L, ChronoUnit.DAYS)
);
}
/**
* 从时间戳型 UUID 中提取 MAC 地址默认使用冒号分隔符
*
* @return MAC 地址字符串
* @throws UUIDException 如果 uuid null
*/
public String extractMACFromUUID() {
return extractMACFromUUID(null);
}
/**
* 从时间戳型 UUID 中提取 MAC 地址并允许自定义分隔符
*
* @param spec 分隔符字符默认为 ":"
* @return MAC 地址字符串
* @throws UUIDException 如果 uuid null
*/
public String extractMACFromUUID(String spec) {
if (uuid == null) {
throw new UUIDException("uuid is null : NullPointerException");
}
if (spec == null) {
spec = ":";
}
long leastSigBits = uuid.getLeastSignificantBits();
long macLong = leastSigBits & 0xFFFFFFFFFFFFL;
byte[] macBytes = new byte[6];
// 提取 MAC 地址的每个字节
for (int i = 0; i < 6; i++) {
macBytes[5 - i] = (byte) (macLong >> (8 * i));
}
StringBuilder mac = new StringBuilder();
// 构造 MAC 地址字符串
for (int i = 0; i < 6; i++) {
mac.append(String.format("%02X", macBytes[i]));
if (i < 5) {
mac.append(spec);
}
}
return mac.toString();
}
}

View File

@ -1,102 +0,0 @@
/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile VersionUtils.java
* LastUpdate 2025-09-09 08:37:33
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.version;
import java.util.Objects;
/**
* 版本工具类提供版本比较相关的方法
*/
public class VersionUtils {
/**
* 判断当前版本是否比另一个版本新
*
* @param now 当前版本号字符串格式如"1.0.0"
* @param other 要比较的版本号字符串格式如"2.0.0"
* @return 如果当前版本更新则返回true否则返回false
*/
public static boolean isNew(String now, String other) {
String[] currentParts = now.split("\\.");
String[] minimumParts = other.split("\\.");
for (
int i = 0;
i < Math.max(currentParts.length, minimumParts.length);
i++
) {
int currentNum = i < currentParts.length
? Integer.parseInt(currentParts[i])
: 0;
int minimumNum = i < minimumParts.length
? Integer.parseInt(minimumParts[i])
: 0;
if (currentNum < minimumNum) {
return true;
} else if (currentNum > minimumNum) {
return false;
}
}
return false;
}
/**
* 判断当前版本是否比另一个版本旧
*
* @param now 当前版本号字符串格式如"1.0.0"
* @param other 要比较的版本号字符串格式如"2.0.0"
* @return 如果当前版本更旧则返回true否则返回false
*/
public static boolean isOld(String now, String other) {
return !equals(now, other) && !isNew(now, other);
}
/**
* 判断两个版本号是否相等
*
* @param now 当前版本号字符串格式如"1.0.0"
* @param other 要比较的版本号字符串格式如"2.0.0"
* @return 如果两个版本号相等则返回true否则返回false
*/
public static boolean equals(String now, String other) {
return Objects.equals(now, other);
}
/**
* 比较两个版本号的大小关系
*
* @param now 当前版本号字符串格式如"1.0.0"
* @param other 要比较的版本号字符串格式如"2.0.0"
* @return 如果当前版本更新返回2如果更旧返回0如果相等返回1
*/
public static byte is(String now, String other) {
if (isNew(now, other)) {
return 2;
} else if (isOld(now, other)) {
return 0;
} else {
return 1;
}
}
}

View File

@ -15,19 +15,18 @@
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile Main.java
* LastUpdate 2025-09-09 08:37:33
* CurrentFile Main.kt
* LastUpdate 2025-09-12 17:11:48
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils;
@file:JvmName("Main")
import com.mingliqiye.utils.springboot.autoconfigure.AutoConfiguration;
import java.io.IOException;
package com.mingliqiye.utils
public class Main {
import com.mingliqiye.utils.springboot.autoconfigure.AutoConfiguration
public static void main(String[] args) throws IOException {
AutoConfiguration.printBanner();
}
fun main() {
AutoConfiguration.printBanner()
}

View File

@ -0,0 +1,83 @@
/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile RandomBytes.kt
* LastUpdate 2025-09-12 17:11:19
* UpdateUser MingLiPro
*/
@file:JvmName("RandomBytes")
package com.mingliqiye.utils.random
import com.mingliqiye.utils.collection.ForEach
import com.mingliqiye.utils.iterator.Range
/**
* 生成指定长度的随机字节数组
* @param length 数组长度
* @return 包含随机字节的数组
*/
fun randomBytes(length: Int): ByteArray {
val bytes = ByteArray(length)
ForEach.forEach(
Range(0, length - 1)
) { i: Int -> bytes[i] = randomByte(0x00.toByte(), 0xff.toByte()) }
return bytes
}
/**
* 生成指定长度的随机字节数组
* 从给定的字节数组中随机选择字节来填充新数组
*
* @param length 要生成的随机字节数组的长度
* @param bytes 用于随机选择的源字节数组
* @return 包含随机字节的新数组
*/
fun randomBytes(length: Int, bytes: ByteArray): ByteArray {
val rbytes = ByteArray(length)
// 从源数组中随机选择字节填充到结果数组中
for (i in 0..<length) {
rbytes[i] = bytes[randomInt(i, bytes.size - 1)]
}
return rbytes
}
/**
* 生成指定范围内的随机字节
* @param from 起始字节值包含
* @param to 结束字节值包含
* @return 指定范围内的随机字节
*/
fun randomByte(from: Byte, to: Byte): Byte {
val fromInt = from.toInt() and 0xFF
val toInt = to.toInt() and 0xFF
val randomValue = randomInt(fromInt, toInt)
return (randomValue and 0xFF).toByte()
}
/**
* 生成指定范围内的随机字节不包含边界值
* @param from 起始字节值不包含
* @param to 结束字节值不包含
* @return 指定范围内的随机字节
*/
fun randomByteNoHave(from: Byte, to: Byte): Byte {
val fromInt = from.toInt() and 0xFF
val toInt = to.toInt() and 0xFF
val randomValue = randomIntNoHave(fromInt, toInt)
return (randomValue and 0xFF).toByte()
}

View File

@ -0,0 +1,60 @@
/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile RandomInt.kt
* LastUpdate 2025-09-12 17:08:32
* UpdateUser MingLiPro
*/
@file:JvmName("RandomInt")
package com.mingliqiye.utils.random
import java.util.concurrent.ThreadLocalRandom
/**
* 生成指定范围内的随机整数
* @param min 最小值包含
* @param max 最大值不包含
* @return 随机整数
*/
fun randomIntNoHave(min: Int, max: Int): Int {
var min = min
var max = max
if (min > max) {
val t = min
min = max
max = t
}
if (min == max) {
return min
}
return ThreadLocalRandom.current().nextInt(min, max)
}
/**
* 生成指定范围内的随机整数
* @param min 最小值包含
* @param max 最大值包含
* @return 随机整数
*/
fun randomInt(min: Int, max: Int): Int {
var max = max
return randomIntNoHave(min, ++max)
}

View File

@ -0,0 +1,54 @@
/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile RandomString.kt
* LastUpdate 2025-09-12 17:10:43
* UpdateUser MingLiPro
*/
@file:JvmName("RandomString")
package com.mingliqiye.utils.random
/**
* 生成指定长度和字符集的随机字符串
*
* @param length 要生成的随机字符串长度
* @param chars 用于生成随机字符串的字符集
* @return 指定长度的随机字符串
*/
fun randomString(length: Int, chars: String): String {
val charsd: Array<String?> = chars.split("".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val sb = StringBuilder(length)
// 循环生成随机字符并拼接
for (i in 0..<length) {
val index = randomInt(0, charsd.size - 1)
sb.append(charsd[index])
}
return sb.toString()
}
/**
* 生成指定长度的随机字符串使用默认字符集(数字+大小写字母)
*
* @param length 要生成的随机字符串长度
* @return 指定长度的随机字符串
*/
fun randomString(length: Int): String {
return randomString(
length, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
)
}

View File

@ -0,0 +1,244 @@
/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile UUID.kt
* LastUpdate 2025-09-12 16:57:52
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.uuid
import com.github.f4b6a3.uuid.UuidCreator
import com.mingliqiye.utils.time.DateTime
import com.mingliqiye.utils.time.DateTimeOffset
import java.io.Serializable
import java.nio.ByteBuffer
import java.time.temporal.ChronoUnit
import java.util.*
import java.util.UUID as JUUID
class UUID : Serializable {
private val uuid: JUUID
companion object {
/**
* 获取 UUIDV1 版本的随机实例
* @return UUID
*/
@JvmStatic
fun getV1(): UUID {
return UUID(UuidCreator.getTimeBased())
}
/**
* 获取 UUIDV4 版本的随机实例
* @return UUID
*/
@JvmStatic
fun getV4(): UUID {
return UUID(UuidCreator.getRandomBased())
}
/**
* 获取 UUIDV1Fast 版本的随机实例
* @return UUID
*/
@JvmStatic
fun getV4Fast(): UUID {
return UUID(UuidCreator.getRandomBasedFast())
}
/**
* 从2个8个字节转换到UUID
* @param lsb 高位 8 字节的 Long
* @param msb 低位 8 字节的 Long
* @return UUID
*/
@JvmStatic
fun of(msb: Long, lsb: Long): UUID {
return UUID(msb, lsb)
}
/**
* 从字符串格式化
* @param uuid 字符串
* @return UUID
*/
@JvmStatic
fun of(uuid: String): UUID {
return UUID(uuid)
}
/**
* 从字节码转换到UUID
* @param array 16字节
* @return UUID
*/
@JvmStatic
fun of(array: ByteArray): UUID {
return UUID(array)
}
}
internal constructor(msb: Long, lsb: Long) {
uuid = JUUID(msb, lsb)
}
internal constructor(uuid: JUUID) {
this.uuid = uuid
}
internal constructor(array: ByteArray) {
val bb = ByteBuffer.wrap(array)
this.uuid = JUUID(bb.getLong(), bb.getLong())
}
internal constructor(uuid: String) {
this.uuid = JUUID.fromString(uuid)
}
/**
* 获取对应的字节码
* @return 字节码
*/
fun toBytes(): ByteArray {
val bb = ByteBuffer.wrap(ByteArray(16))
bb.putLong(uuid.mostSignificantBits)
bb.putLong(uuid.leastSignificantBits)
return bb.array()
}
/**
* 获取Java的UUID对象
* @return Java的UUID对象
*/
fun getUuid(): JUUID {
return uuid
}
/**
* UUID 转换为字符串表示默认使用小写格式
* @param u 是否大写
* @return UUID 字符串
*/
fun getString(u: Boolean): String {
return if (u) {
uuid.toString().uppercase(Locale.ROOT)
} else {
uuid.toString()
}
}
/**
* UUID 转换为字符串表示默认使用小写格式
*
* @return UUID 字符串
*/
fun getString(): String {
return getString(false)
}
@Deprecated("使用 getString()", ReplaceWith("getString"), level = DeprecationLevel.WARNING)
fun toUUIDString(): String {
return this.getString()
}
@Deprecated("使用 getString(u:Boolean)", ReplaceWith("getString(u)"), level = DeprecationLevel.WARNING)
fun toUUIDString(u: Boolean): String {
return this.getString(u)
}
/**
* 从时间戳型 UUID 中提取时间戳并转换为 DateTime 对象
*
* @return 对应的 DateTime 对象如果 不是 时间戳V1版本 返回 null
*/
fun getDateTime(): DateTime? {
if (uuid.version() != 1) {
return null
}
return DateTime.of(uuid.timestamp() / 10000).add(
DateTimeOffset.of(-141427L, ChronoUnit.DAYS)
)
}
/**
* 从时间戳型 UUID 中提取 MAC 地址默认使用冒号分隔符
*
* @return MAC 地址字符串
*/
fun extractMACFromUUID(): String {
return extractMACFromUUID(null)
}
/**
* 从时间戳型 UUID 中提取 MAC 地址并允许自定义分隔符
*
* @param spec 分隔符字符默认为 ":"
* @return MAC 地址字符串
*/
fun extractMACFromUUID(spec: String?): String {
var spec = spec
if (spec == null) {
spec = ":"
}
val leastSigBits = uuid.leastSignificantBits
val macLong = leastSigBits and 0xFFFFFFFFFFFFL
val macBytes = ByteArray(6)
for (i in 0..5) {
macBytes[5 - i] = (macLong shr (8 * i)).toByte()
}
val mac = StringBuilder()
for (i in 0..5) {
mac.append(String.format("%02X", macBytes[i]))
if (i < 5) {
mac.append(spec)
}
}
return mac.toString()
}
/**
* 返回此 UUID 的字符串表示包含版本信息和时间戳如果是版本1
*
* @return UUID 的详细字符串表示
*/
override fun toString(): String {
return "UUID(uuid=${getString()},version=${uuid.version()})"
}
/**
* 判断两个 UUID 是否相等
*
* @param other 比较对象
* @return 如果相等返回 true否则返回 false
*/
override fun equals(other: Any?): Boolean {
return uuid == other
}
/**
* 计算此 UUID 的哈希码
*
* @return 哈希码值
*/
override fun hashCode(): Int {
return uuid.hashCode()
}
}

View File

@ -0,0 +1,99 @@
/*
* Copyright 2025 mingliqiye
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile VersionUtils.kt
* LastUpdate 2025-09-12 15:09:57
* UpdateUser MingLiPro
*/
@file:JvmName("VersionUtils")
package com.mingliqiye.utils.version
import kotlin.math.max
/**
* 判断是否需要更新
* @param now 当前版本
* @param other 比较版本
* @return 当前版本需要更新
* @since 3.2.7
*/
fun isNew(now: String, other: String): Boolean {
val otherA = now.split(".")
val otherB = other.split(".")
val maxLen = max(otherA.size, otherB.size)
for (i in 0..<maxLen) {
val a = if (otherA.size > i) otherA[i].toInt() else null
val b = if (otherB.size > i) otherB[i].toInt() else null
if (a == null) {
return true
}
if (b == null) {
return false
}
if (a != b) {
return a < b
}
}
return false
}
/**
* 判断版本是否小于当前
* @param now 当前版本
* @param other 比较版本
* @return 是否小于
*
*/
fun isOld(now: String, other: String): Boolean {
return (now != other) && !isNew(now, other)
}
/**
* 判断是否版本相同
* @param now 当前版本
* @param other 比较版本
* @return 是否相同
*/
fun equals(now: String, other: String): Boolean {
return now == other
}
/**
* 判断是否需要更新
* @param now 当前版本
* @param other 比较版本
* @return null->版本相同 true->需要更新 false->不需要更新
*/
@JvmName("is")
fun isOther(now: String, other: String): Boolean? {
return if (isNew(now, other)) {
true
} else if (isOld(now, other)) {
false
} else {
null
}
}