diff --git a/hutool-core/src/main/java/cn/hutool/core/text/SpecialSymbolUtil.java b/hutool-core/src/main/java/cn/hutool/core/text/SpecialSymbolUtil.java
deleted file mode 100644
index 968b62ffa..000000000
--- a/hutool-core/src/main/java/cn/hutool/core/text/SpecialSymbolUtil.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package cn.hutool.core.text;
-
-import java.math.BigInteger;
-
-/**
- * 符号工具类
- * @author dazer & neusoft
- * @date 2021/3/26 12:21
- * 别名:Symbol or special signal or Special symbols
- * 说明:获取常见的特殊符号,如:带圈数字、
- *
- * {@link UnicodeUtil}
- * @link 百度百科 https://baike.baidu.com/item/%E7%89%B9%E6%AE%8A%E5%AD%97%E7%AC%A6/112715?fr=aladdin
- * @link 360百科 https://baike.so.com/doc/5408938-5646935.html
- * @link 百科 https://www.baike.com/wikiid/3469869303298461399?prd=home_search&search_id=5bm572esa2k000&view_id=1takcxx7kjc000
- * @link coolsymbol https://coolsymbol.com/
- * @link 维基百科wikipedia https://en.wikipedia.org/wiki/List_of_Unicode_characters#Unicode_symbols
- *
- * @since 5.6.2
- */
-public class SpecialSymbolUtil {
- public static final String UNICODE_START_CHAR = "\\u";
- private SpecialSymbolUtil(){}
-
- /**
- * 获取带圈数字 /封闭式字母数字 ,从1-20,超过1-20报错
- *
- * 0 1 2 3 4 5 6 7 8 9 A B C D E F
- * U+246x ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯
- * U+247x ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿
- * U+248x ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏
- * U+249x ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟
- * U+24Ax ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯
- * U+24Bx ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ
- * U+24Cx Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ
- * U+24Dx ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ
- * U+24Ex ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯
- * U+24Fx ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
- * @link Unicode_symbols https://en.wikipedia.org/wiki/List_of_Unicode_characters#Unicode_symbols
- * @link Enclosed Alphanumerics https://en.wikipedia.org/wiki/Enclosed_Alphanumerics
- *
- *
- * System.out.println(enclosedAlphanumericsStyle1ByInt(1));
- * System.out.println(enclosedAlphanumericsStyle1ByInt(2));
- * System.out.println(enclosedAlphanumericsStyle1ByInt(3));
- * System.out.println(enclosedAlphanumericsStyle1ByInt(4));
- * System.out.println(enclosedAlphanumericsStyle1ByInt(14));
- * System.out.println(enclosedAlphanumericsStyle1ByInt(18));
- * System.out.println(enclosedAlphanumericsStyle1ByInt(19));
- * System.out.println(enclosedAlphanumericsStyle1ByInt(20));
- *
- *
- * @param number 十进制数字,从1、-->10、11--->20
- * @return ①②③④⑤⑥⑦⑧⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳
- */
- public static String enclosedNumericsByInt(int number) {
- if (number <= 0 || number > 20) {
- throw new IllegalArgumentException("number取值范围是[1-20]的正整数,包含1和20");
- }
- String start = "①";
- String unicodeStart = UnicodeUtil.toUnicode(start).substring(UNICODE_START_CHAR.length(),
- UnicodeUtil.toUnicode(start).length() - 1);
- // begin: U+246x的24
- String beginHex = unicodeStart.substring(0, 2);
- // U+246x的6
- String middleHex = number >= 17 ? "7" : "6";
- // A
- String endHex = Integer.toHexString(number >= 17 ? number - 17 : number - 1);
- // U + 24 + 60
- String unicodeStr = UNICODE_START_CHAR + beginHex + middleHex + endHex;
- return UnicodeUtil.toString(unicodeStr);
- }
-
- /**
- * 获取带圈字母 /封闭式字母 ,从a-z or A-Z
- * 根据字符 获取 Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ
- *
- * System.out.println(encloseAlphabetByChar( 'A'));
- * System.out.println(encloseAlphabetByChar( 'a'));
- * System.out.println(encloseAlphabetByChar( 'z'));
- * System.out.println(encloseAlphabetByChar( 'Z'))
- *
- * @author dazer
- * @param letter 字母,不区分大小写,'a'、'b'、'c'、'd'...'x'、'y'、'z'; 'A'、'B'...'Z'
- * @date 2021/3/26 18:10
- */
- public static String encloseAlphabetByChar(char letter) {
- if (!(letter >= 'a' && letter <= 'z' || letter >= 'A' && letter <= 'Z')) {
- throw new IllegalArgumentException("number取值范围是[a-z]、[A-Z]的字符");
- }
- // \u24b6
- String start = "Ⓐ";
- String hexStr = UnicodeUtil.toUnicode(start).substring(UNICODE_START_CHAR.length());
- int difference = letter >= 'a' && letter <= 'z' ? (letter - (int)'a') : (letter - (int)'A');
- String hex = new BigInteger(hexStr, 16).add(new BigInteger(String.valueOf(difference), 10)).toString(16);
- //
- String unicodeStr = UNICODE_START_CHAR + hex;
- return UnicodeUtil.toString(unicodeStr);
- }
-}
diff --git a/hutool-core/src/main/java/cn/hutool/core/text/UnicodeSymbolUtil.java b/hutool-core/src/main/java/cn/hutool/core/text/UnicodeSymbolUtil.java
new file mode 100644
index 000000000..8374c2d55
--- /dev/null
+++ b/hutool-core/src/main/java/cn/hutool/core/text/UnicodeSymbolUtil.java
@@ -0,0 +1,228 @@
+package cn.hutool.core.text;
+
+import java.math.BigInteger;
+
+/**
+ * 符号工具类
+ * @author dazer & neusoft
+ * @date 2021/3/26 12:21
+ * 别名:Symbol or special signal or Special symbols
+ * 说明:获取常见的特殊符号,如:带圈数字、
+ *
+ * {@link UnicodeUtil}
+ * @link 百度百科 https://baike.baidu.com/item/%E7%89%B9%E6%AE%8A%E5%AD%97%E7%AC%A6/112715?fr=aladdin
+ * @link 360百科 https://baike.so.com/doc/5408938-5646935.html
+ * @link 百科 https://www.baike.com/wikiid/3469869303298461399?prd=home_search&search_id=5bm572esa2k000&view_id=1takcxx7kjc000
+ * @link coolsymbol https://coolsymbol.com/
+ * @link 维基百科wikipedia-Unicode_symbols https://en.wikipedia.org/wiki/List_of_Unicode_characters#Unicode_symbols
+ * @link 维基百科wikipedia-Unicode字符列表 https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%88%97%E8%A1%A8
+ *
+ * @since 5.6.2
+ */
+public class UnicodeSymbolUtil {
+ public static final String UNICODE_START_CHAR = "\\u";
+ private UnicodeSymbolUtil(){}
+
+ /**
+ * 封闭式字母数字(带圆圈数字) ,从1-20,超过1-20报错
+ *
+ * 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ * U+246x ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯
+ * U+247x ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿
+ * U+248x ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏
+ * U+249x ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟
+ * U+24Ax ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯
+ * U+24Bx ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ
+ * U+24Cx Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ
+ * U+24Dx ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ
+ * U+24Ex ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯
+ * U+24Fx ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿
+ * @link Unicode_symbols https://en.wikipedia.org/wiki/List_of_Unicode_characters#Unicode_symbols
+ * @link Enclosed Alphanumerics https://en.wikipedia.org/wiki/Enclosed_Alphanumerics
+ *
+ *
+ * System.out.println(enclosedNumericsByInt(1));
+ * System.out.println(enclosedNumericsByInt(2));
+ * System.out.println(enclosedNumericsByInt(3));
+ * System.out.println(enclosedNumericsByInt(4));
+ * System.out.println(enclosedNumericsByInt(14));
+ * System.out.println(enclosedNumericsByInt(18));
+ * System.out.println(enclosedNumericsByInt(19));
+ * System.out.println(enclosedNumericsByInt(20));
+ *
+ *
+ * @param number 十进制数字,取值,从1-->20
+ * @return ①②③④⑤⑥⑦⑧⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳
+ */
+ public static String enclosedNumericsByInt(int number) {
+ if (!(number >=1 && number <= 20)) {
+ throw new IllegalArgumentException("封闭式数字的number取值范围是[1-20]的正整数,包含1和20");
+ }
+ int difference = number - 1;
+ return unicodeAddDifference("①", difference);
+ }
+
+ /**
+ * 封闭式字母(获取带圈字母) ,从a-z or A-Z
+ * 根据字符 获取 Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓜ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ
+ *
+ * System.out.println(encloseAlphabetByChar( 'A'));
+ * System.out.println(encloseAlphabetByChar( 'a'));
+ * System.out.println(encloseAlphabetByChar( 'z'));
+ * System.out.println(encloseAlphabetByChar( 'Z'));
+ *
+ * @author dazer
+ * @param letter 字母,不区分大小写,'a'、'b'、'c'、'd'...'x'、'y'、'z'; 'A'、'B'...'Z'
+ * @date 2021/3/26 18:10
+ */
+ public static String encloseAlphabetByChar(char letter) {
+ letter = (letter + "").toLowerCase().charAt(0);
+ if (!(letter >= 'a' && letter <= 'z')) {
+ throw new IllegalArgumentException("封闭式字母number取值范围是[a-z]、[A-Z]的字符");
+ }
+ int difference = (letter - (int)'a');
+ return unicodeAddDifference("Ⓐ", difference);
+ }
+
+ /**
+ * 获取大写的罗马数字
+ * 维基百科-Number_Forms: https://en.wikipedia.org/wiki/List_of_Unicode_characters#Number_Forms
+ * 百度百科-罗马数字: https://baike.baidu.com/item/%E7%BD%97%E9%A9%AC%E6%95%B0%E5%AD%97
+ *
+ * 0 1 2 3 4 5 6 7 8 9 A B C D E F + * U+215x ⅐ ⅑ ⅒ ⅓ ⅔ ⅕ ⅖ ⅗ ⅘ ⅙ ⅚ ⅛ ⅜ ⅝ ⅞ ⅟ + * U+216x Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ Ⅵ Ⅶ Ⅷ Ⅸ Ⅹ Ⅺ Ⅻ Ⅼ Ⅽ Ⅾ Ⅿ + * U+217x ⅰ ⅱ ⅲ ⅳ ⅴ ⅵ ⅶ ⅷ ⅸ ⅹ ⅺ ⅻ ⅼ ⅽ ⅾ ⅿ + *+ *
+ * System.out.println(romanNumeralsUppercaseByInt(1));
+ * System.out.println(romanNumeralsUppercaseByInt(12));
+ *
+ * @return 罗马数字-大写, Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ Ⅵ Ⅶ Ⅷ Ⅸ Ⅹ Ⅺ Ⅻ Ⅼ Ⅽ Ⅾ Ⅿ
+ * 罗马数字-小写, ⅰ ⅱ ⅲ ⅳ ⅴ ⅵ ⅶ ⅷ ⅸ ⅹ ⅺ ⅻ ⅼ ⅽ ⅾ ⅿ
+ */
+ public static String romanNumeralsUppercaseByInt(int number) {
+ if (!(number >=1 && number <= 12)) {
+ throw new IllegalArgumentException("大写罗马数字的number取值范围是[1-12]的正整数,包含1和12");
+ }
+ int difference = number - 1;
+ return unicodeAddDifference("Ⅰ", difference);
+ }
+
+ /**
+ * 获取小写的罗马数字
+ * 维基百科-Number_Forms: https://en.wikipedia.org/wiki/List_of_Unicode_characters#Number_Forms
+ * 百度百科-罗马数字: https://baike.baidu.com/item/%E7%BD%97%E9%A9%AC%E6%95%B0%E5%AD%97
+ * + * 0 1 2 3 4 5 6 7 8 9 A B C D E F + * U+215x ⅐ ⅑ ⅒ ⅓ ⅔ ⅕ ⅖ ⅗ ⅘ ⅙ ⅚ ⅛ ⅜ ⅝ ⅞ ⅟ + * U+216x Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ Ⅵ Ⅶ Ⅷ Ⅸ Ⅹ Ⅺ Ⅻ Ⅼ Ⅽ Ⅾ Ⅿ + * U+217x ⅰ ⅱ ⅲ ⅳ ⅴ ⅵ ⅶ ⅷ ⅸ ⅹ ⅺ ⅻ ⅼ ⅽ ⅾ ⅿ + *+ *
+ * System.out.println(romanNumeralsLowercaseByInt(1));
+ * System.out.println(romanNumeralsLowercaseByInt(12));
+ *
+ * @return 罗马数字-大写, Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ Ⅵ Ⅶ Ⅷ Ⅸ Ⅹ Ⅺ Ⅻ Ⅼ Ⅽ Ⅾ Ⅿ
+ * 罗马数字-小写, ⅰ ⅱ ⅲ ⅳ ⅴ ⅵ ⅶ ⅷ ⅸ ⅹ ⅺ ⅻ ⅼ ⅽ ⅾ ⅿ
+ */
+ public static String romanNumeralsLowercaseByInt(int number) {
+ if (!(number >=1 && number <= 12)) {
+ throw new IllegalArgumentException("大写罗马数字的number取值范围是[1-12]的正整数,包含1和12");
+ }
+ int difference = number - 1;
+ return unicodeAddDifference("ⅰ", difference);
+ }
+
+ /**
+ * 黑桃♠扑克牌
+ * 黑桃(spade).对应宝剑,象征正义、战争与灾难。spade是铲子,也是武器。象征战争。
+ * -------
+ * 黑桃♠ 🂡 spade
+ * 红桃♥ 🂱 Heart
+ * 方块♦ 🃁 Diamond
+ * 梅花♣ 🃑 Club
+ * -------
+ * https://en.wikipedia.org/wiki/Playing_cards_in_Unicode
+ *
+ * System.out.println(playingCardsSpadeByInt(1));
+ * System.out.println(playingCardsSpadeByInt(2));
+ * System.out.println(playingCardsSpadeByInt(3));
+ * System.out.println(playingCardsSpadeByInt(13));
+ *
+ * @param number 1-13
+ * @return 黑桃扑克牌,🂡---->🂮
+ * 🂡🂢🂣🂤🂥🂦🂧🂨🂩🂪🂫🂬🂭🂮
+ * 扑克牌unicode特殊是两位
+ */
+ public static String playingCardsSpadeByInt(int number) {
+ if (!(number >=1 && number <= 13)) {
+ throw new IllegalArgumentException("扑克牌♠number取值范围是[1-13]的正整数,包含1和13");
+ }
+ int difference = number - 1;
+ return unicodeAddDifference("🂡", difference);
+ }
+
+ /**
+ * 红桃♥扑克牌
+ */
+ public static String playingCardsHeartByInt(int number) {
+ if (!(number >=1 && number <= 13)) {
+ throw new IllegalArgumentException("扑克牌♥number取值范围是[1-13]的正整数,包含1和13");
+ }
+ int difference = number - 1;
+ return unicodeAddDifference("🂱", difference);
+ }
+
+ /**
+ * 方块♦扑克牌
+ */
+ public static String playingCardsDiamondByInt(int number) {
+ if (!(number >=1 && number <= 13)) {
+ throw new IllegalArgumentException("扑克牌方块♦number取值范围是[1-13]的正整数,包含1和13");
+ }
+ int difference = number - 1;
+ return unicodeAddDifference("🃑", difference);
+ }
+
+ /**
+ * 梅花♣扑克牌
+ */
+ public static String playingCardsClubByInt(int number) {
+ if (!(number >=1 && number <= 13)) {
+ throw new IllegalArgumentException("扑克牌梅花♣number取值范围是[1-13]的正整数,包含1和13");
+ }
+ int difference = number - 1;
+ return unicodeAddDifference("🂱", difference);
+ }
+
+ /**
+ * 一位unicode从开始特殊字符,便宜num个数字
+ * @param startSymbol 开始的特殊字符,如:Ⓐ、①
+ * @return startSymbol + difference 之后的特殊字符,如:Ⓐ + 2 = Ⓒ
+ */
+ private static String unicodeAddDifference(String startSymbol, int difference) {
+ // unicode有两种形式
+ // k = U+1F0AE = 🂮 = "\uD83C\uDCAE"
+ // Ⓐ \u24b6
+ int unicodeLen = 6;
+ String unicode = UnicodeUtil.toUnicode(startSymbol);
+ if (unicode.length() <= unicodeLen) {
+ // 8位实现 Ⓐ \u24b6
+ String hexStr = unicode.substring(UNICODE_START_CHAR.length());
+ String hex = new BigInteger(hexStr, 16).add(new BigInteger(String.valueOf(difference), 10)).toString(16);
+ //
+ String unicodeStr = UNICODE_START_CHAR + hex;
+ return UnicodeUtil.toString(unicodeStr);
+ } else {
+ // 16实现 🂮 = "\uD83C\uDCAE"
+ String unicode1 = unicode.substring(0, unicodeLen);
+ String unicode2 = unicode.substring(unicodeLen);
+ String hexStr2 = unicode2.substring(UNICODE_START_CHAR.length());
+ String hex2 = new BigInteger(hexStr2, 16).add(new BigInteger(String.valueOf(difference), 10)).toString(16);
+ //
+ String unicodeStr2 = UNICODE_START_CHAR + hex2;
+ return UnicodeUtil.toString(unicode1 + unicodeStr2);
+ }
+ }
+}