diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt index 1895c4d..0af1f01 100644 --- a/ProgressOfTesting.txt +++ b/ProgressOfTesting.txt @@ -1,6 +1,6 @@ -[ ] 未开始测试 - 8 (11.94%) +[ ] 未开始测试 - 7 (10.45%) [-] 测试未完成 - 8 (11.94%) -[Y] 测试完成 - 29 (43.28%) +[Y] 测试完成 - 30 (44.78%) [x] 无需测试 - 22 (32.84%) xyz.zhouxy.plusone.commons @@ -91,7 +91,7 @@ xyz.zhouxy.plusone.commons IdWorker.java [Y] Numbers.java [Y] OptionalTools.java [Y] - RandomTools.java [ ] + RandomTools.java [Y] RegexTools.java [ ] SnowflakeIdGenerator.java [Y] StringTools.java [Y] diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/RandomTools.java b/src/main/java/xyz/zhouxy/plusone/commons/util/RandomTools.java index f9bc4a2..07f54bf 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/RandomTools.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/RandomTools.java @@ -16,6 +16,7 @@ package xyz.zhouxy.plusone.commons.util; +import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Objects; import java.util.Random; @@ -23,14 +24,40 @@ import java.util.concurrent.ThreadLocalRandom; import javax.annotation.Nonnull; +/** + * 随机工具类 + *
+ * 建议调用方自行维护 Random 对象 + *
+ * @author ZhouXY + */ public final class RandomTools { - public static final SecureRandom DEFAULT_SECURE_RANDOM = new SecureRandom(); + private static final SecureRandom DEFAULT_SECURE_RANDOM; + + static { + SecureRandom secureRandom = null; + try { + secureRandom = SecureRandom.getInstanceStrong(); // 获取高强度安全随机数生成器 + } + catch (NoSuchAlgorithmException e) { + secureRandom = new SecureRandom(); // 获取普通的安全随机数生成器 + } + DEFAULT_SECURE_RANDOM = secureRandom; + } public static final String CAPITAL_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; public static final String LOWERCASE_LETTERS = "abcdefghijklmnopqrstuvwxyz"; public static final String NUMBERS = "0123456789"; + public static SecureRandom defaultSecureRandom() { + return DEFAULT_SECURE_RANDOM; + } + + public static ThreadLocalRandom currentThreadLocalRandom() { + return ThreadLocalRandom.current(); + } + /** * 使用传入的随机数生成器,生成指定长度的字符串 * diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/RandomToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/RandomToolsTests.java new file mode 100644 index 0000000..fcf5f44 --- /dev/null +++ b/src/test/java/xyz/zhouxy/plusone/commons/util/RandomToolsTests.java @@ -0,0 +1,89 @@ +package xyz.zhouxy.plusone.commons.util; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.security.SecureRandom; +import java.util.Random; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +@SuppressWarnings("null") +public class RandomToolsTests { + + private static Random random; + private static SecureRandom secureRandom; + private static char[] sourceCharactersArray; + private static String sourceCharactersString; + + @BeforeAll + public static void setUp() { + random = new Random(); + secureRandom = new SecureRandom(); + sourceCharactersArray = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); + sourceCharactersString = "abcdefghijklmnopqrstuvwxyz"; + } + + @Test + public void randomStr_NullRandom_ThrowsException() { + assertThrows(IllegalArgumentException.class, + () -> RandomTools.randomStr(null, sourceCharactersArray, 5)); + assertThrows(IllegalArgumentException.class, + () -> RandomTools.randomStr(null, sourceCharactersString, 5)); + } + + @Test + public void randomStr_NullSourceCharacters_ThrowsException() { + assertThrows(IllegalArgumentException.class, () -> RandomTools.randomStr(random, (char[]) null, 5)); + assertThrows(IllegalArgumentException.class, () -> RandomTools.randomStr(random, (String) null, 5)); + } + + @Test + public void randomStr_NegativeLength_ThrowsException() { + assertThrows(IllegalArgumentException.class, () -> RandomTools.randomStr(random, sourceCharactersArray, -1)); + } + + @Test + public void randomStr_ZeroLength_ReturnsEmptyString() { + assertAll( + () -> assertEquals("", RandomTools.randomStr(random, sourceCharactersArray, 0)), + () -> assertEquals("", RandomTools.randomStr(random, sourceCharactersString, 0)), + () -> assertEquals("", RandomTools.randomStr(secureRandom, sourceCharactersArray, 0)), + () -> assertEquals("", RandomTools.randomStr(secureRandom, sourceCharactersString, 0))); + } + + @Test + public void randomStr_PositiveLength_ReturnsRandomString() { + assertAll( + () -> assertEquals(5, RandomTools.randomStr(random, sourceCharactersArray, 5).length()), + () -> assertEquals(5, RandomTools.randomStr(random, sourceCharactersString, 5).length()), + () -> assertEquals(5, RandomTools.randomStr(secureRandom, sourceCharactersArray, 5).length()), + () -> assertEquals(5, RandomTools.randomStr(secureRandom, sourceCharactersString, 5).length())); + } + + @Test + public void randomStr_ReturnsRandomString() { + String result = RandomTools.randomStr(sourceCharactersArray, 5); + assertEquals(5, result.length()); + } + + @Test + public void randomStr_StringSourceCharacters_ReturnsRandomString() { + String result = RandomTools.randomStr(sourceCharactersString, 5); + assertEquals(5, result.length()); + } + + @Test + public void secureRandomStr_ReturnsRandomString() { + String result = RandomTools.secureRandomStr(sourceCharactersArray, 5); + assertEquals(5, result.length()); + } + + @Test + public void secureRandomStr_StringSourceCharacters_ReturnsRandomString() { + String result = RandomTools.secureRandomStr(sourceCharactersString, 5); + assertEquals(5, result.length()); + } +}