11 Commits

Author SHA1 Message Date
06abba8765 Merge pull request 'v0.0.10' (#9) from dev into master
Reviewed-on: #9
2026-06-30 07:38:00 +00:00
Timi
21480a37a2 v0.0.10
All checks were successful
CI/CD / build-deploy (pull_request) Successful in 10s
2026-06-30 15:35:43 +08:00
4e8351fee9 Merge pull request 'v0.0.9' (#8) from dev into master
Reviewed-on: #8
2026-06-30 07:23:51 +00:00
Timi
1017129c1a v0.0.9
All checks were successful
CI/CD / build-deploy (pull_request) Successful in 9s
2026-06-30 15:23:19 +08:00
Timi
50d9296952 add Text.randomPassword 2026-06-11 12:08:09 +08:00
Timi
4162b75de9 fix random text pool 2026-06-08 19:17:45 +08:00
97809cd321 Merge pull request 'v0.0.8' (#7) from dev into master
Reviewed-on: #7
2026-06-05 03:59:55 +00:00
Timi
801a945991 v0.0.8
All checks were successful
CI/CD / build-deploy (pull_request) Successful in 12s
2026-06-05 11:59:41 +08:00
Timi
112e6290f0 add random text pool 2026-06-05 11:59:35 +08:00
b9d47baa1a Merge pull request 'v0.0.7' (#6) from dev into master
Reviewed-on: #6
2026-06-02 16:11:14 +00:00
Timi
ceb781292d v0.0.7
All checks were successful
CI/CD / build-deploy (pull_request) Successful in 11s
2026-06-03 00:05:40 +08:00
4 changed files with 86 additions and 18 deletions

View File

@@ -6,7 +6,7 @@
<groupId>com.imyeyu.utils</groupId> <groupId>com.imyeyu.utils</groupId>
<artifactId>timi-utils</artifactId> <artifactId>timi-utils</artifactId>
<version>0.0.6</version> <version>0.0.10</version>
<properties> <properties>
<maven.test.skip>true</maven.test.skip> <maven.test.skip>true</maven.test.skip>
@@ -91,7 +91,7 @@
<dependency> <dependency>
<groupId>com.imyeyu.java</groupId> <groupId>com.imyeyu.java</groupId>
<artifactId>timi-java</artifactId> <artifactId>timi-java</artifactId>
<version>0.0.4</version> <version>0.0.5</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>de.mkammerer</groupId> <groupId>de.mkammerer</groupId>
@@ -108,7 +108,7 @@
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>1.18.34</version> <version>1.18.46</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -52,8 +52,8 @@ public class Regex {
/** 用户名 (4-16 位字母、数字、下划线) */ /** 用户名 (4-16 位字母、数字、下划线) */
public static final String USERNAME = "^[a-zA-Z0-9_]{4,16}$"; public static final String USERNAME = "^[a-zA-Z0-9_]{4,16}$";
/** 密码 (6-18 位,包含字母和数字) */ /** 密码 (6-18 位,包含字母和数字,允许特殊字符) */
public static final String PASSWORD = "^(?=.*[a-zA-Z])(?=.*\\d)[a-zA-Z0-9]{6,18}$"; public static final String PASSWORD = "^(?=.*[a-zA-Z])(?=.*\\d)[a-zA-Z0-9!#$%&()*+,\\-./:;<=>?@\\[\\]\\^_`{|}~]{6,32}$";
/** 中文字符 */ /** 中文字符 */
public static final String CHINESE_CHAR = "^[\\u4e00-\\u9fa5]+$"; public static final String CHINESE_CHAR = "^[\\u4e00-\\u9fa5]+$";

View File

@@ -15,8 +15,16 @@ import java.util.UUID;
*/ */
public class Text { public class Text {
public static String LETTER_POOL = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static String NUMBER_POOL = "0123456789";
public static String LETTER_NUMBER_POOL = LETTER_POOL + NUMBER_POOL;
public static String PASSWORD_CHAR_POOL = LETTER_NUMBER_POOL + "!#$%&()*+,-./:;<=>?@[]^_`{|}~";
/** 十六进制小写 */ /** 十六进制小写 */
public static char[] HEX_DIGITS_LOWER = "0123456789abcdef".toCharArray(); public static char[] HEX_DIGITS_LOWER = (NUMBER_POOL + "abcdef").toCharArray();
/** /**
* 是否为半角字符 * 是否为半角字符
@@ -75,8 +83,8 @@ public class Text {
* @return true 时全部其他字符串和比较字符串一致 * @return true 时全部其他字符串和比较字符串一致
*/ */
public static boolean eqAnd(String string, String... other) { public static boolean eqAnd(String string, String... other) {
for (int i = 0; i < other.length; i++) { for (String s : other) {
if (!string.equals(other[i])) { if (!string.equals(s)) {
return false; return false;
} }
} }
@@ -91,8 +99,8 @@ public class Text {
* @return true 时其他字符串存在和比较字符串一致 * @return true 时其他字符串存在和比较字符串一致
*/ */
public static boolean eqOr(String string, String... other) { public static boolean eqOr(String string, String... other) {
for (int i = 0; i < other.length; i++) { for (String s : other) {
if (!string.equals(other[i])) { if (!string.equals(s)) {
return false; return false;
} }
} }
@@ -107,8 +115,8 @@ public class Text {
* @return true 时全部其他字符串和比较字符串一致 * @return true 时全部其他字符串和比较字符串一致
*/ */
public static boolean eqIgnoreCaseAnd(String string, String... other) { public static boolean eqIgnoreCaseAnd(String string, String... other) {
for (int i = 0; i < other.length; i++) { for (String s : other) {
if (!string.equalsIgnoreCase(other[i])) { if (!string.equalsIgnoreCase(s)) {
return false; return false;
} }
} }
@@ -123,8 +131,8 @@ public class Text {
* @return true 时其他字符串存在和比较字符串一致 * @return true 时其他字符串存在和比较字符串一致
*/ */
public static boolean eqIgnoreCaseOr(String string, String... other) { public static boolean eqIgnoreCaseOr(String string, String... other) {
for (int i = 0; i < other.length; i++) { for (String s : other) {
if (string.equalsIgnoreCase(other[i])) { if (string.equalsIgnoreCase(s)) {
return true; return true;
} }
} }
@@ -141,8 +149,8 @@ public class Text {
public static boolean containsIgnoreCase(String string, String... other) { public static boolean containsIgnoreCase(String string, String... other) {
String stringUpper = string.toUpperCase(); String stringUpper = string.toUpperCase();
String stringLower = string.toLowerCase(); String stringLower = string.toLowerCase();
for (int i = 0; i < other.length; i++) { for (String s : other) {
if (stringLower.contains(other[i].toLowerCase()) || stringUpper.contains(other[i].toUpperCase())) { if (stringLower.contains(s.toLowerCase()) || stringUpper.contains(s.toUpperCase())) {
return true; return true;
} }
} }
@@ -150,18 +158,38 @@ public class Text {
} }
public static String randomString(int length) { public static String randomString(int length) {
return randomString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", length); return randomString(LETTER_NUMBER_POOL, length);
} }
public static String randomString(String pool, int length) { public static String randomString(String pool, int length) {
SecureRandom r = new SecureRandom(); SecureRandom r = new SecureRandom();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
sb.append(pool.charAt(r.nextInt(pool.length() - 1))); sb.append(pool.charAt(r.nextInt(pool.length())));
} }
return sb.toString(); return sb.toString();
} }
public static String randomPassword(int length) {
if (length < 6 || 32 < length) {
throw new IllegalArgumentException("Password length must be between 6 and 32");
}
SecureRandom r = new SecureRandom();
char[] chars = new char[length];
chars[0] = LETTER_POOL.charAt(r.nextInt(LETTER_POOL.length()));
chars[1] = NUMBER_POOL.charAt(r.nextInt(NUMBER_POOL.length()));
for (int i = 2; i < length; i++) {
chars[i] = PASSWORD_CHAR_POOL.charAt(r.nextInt(PASSWORD_CHAR_POOL.length()));
}
for (int i = chars.length - 1; 0 < i; i--) {
int j = r.nextInt(i + 1);
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
return new String(chars);
}
/** /**
* 较短的临时 UUID如果使用在庞大的数据里很可能会发生重复 * 较短的临时 UUID如果使用在庞大的数据里很可能会发生重复
* *
@@ -403,4 +431,8 @@ public class Text {
public static String underscoreClassName(Class<?> clazz) { public static String underscoreClassName(Class<?> clazz) {
return camelCase2underscore(clazz.getSimpleName()); return camelCase2underscore(clazz.getSimpleName());
} }
public static String bizClassName(Class<?> clazz) {
return underscoreClassName(clazz).toUpperCase();
}
} }

View File

@@ -0,0 +1,36 @@
package test;
import com.imyeyu.utils.Regex;
import com.imyeyu.utils.Text;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* @author 夜雨
* @since 2026-06-11 14:00
*/
public class TestRegex {
@Test
public void testPassword() {
assert Regex.isMatch(Regex.PASSWORD, "abc123");
assert Regex.isMatch(Regex.PASSWORD, "abc123!");
assert Regex.isMatch(Regex.PASSWORD, "Abc123[]^_`{|}~");
assert Regex.isMatch(Regex.PASSWORD, "A1!#$%&*+,-./:@?");
for (int i = 0; i < 20; i++) {
assert Regex.isMatch(Regex.PASSWORD, Text.randomPassword(20));
}
assert Regex.isNotMatch(Regex.PASSWORD, "abcdef!");
assert Regex.isNotMatch(Regex.PASSWORD, "123456!");
assert Regex.isNotMatch(Regex.PASSWORD, "Ab1!");
assert Regex.isNotMatch(Regex.PASSWORD, "Abcdefghijklmnopqrstuvwxzy123456!");
assert Regex.isNotMatch(Regex.PASSWORD, "Abc123\\");
assert Regex.isNotMatch(Regex.PASSWORD, "Abc123\"");
assert Regex.isNotMatch(Regex.PASSWORD, "Abc123'");
assert Regex.isNotMatch(Regex.PASSWORD, "Abc123 ");
assertThrows(IllegalArgumentException.class, () -> Text.randomPassword(5));
assertThrows(IllegalArgumentException.class, () -> Text.randomPassword(33));
}
}