diff --git a/hutool-core/src/main/java/cn/hutool/core/util/RadixUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/RadixUtil.java new file mode 100644 index 000000000..c2bda127f --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/util/RadixUtil.java @@ -0,0 +1,120 @@ +package cn.hutool.core.util; + +/** + * 把一个十进制整数根据自己定义的进制规则进行转换 + * + *

主要应用一下情况:

+ * + * + * @author xl7@qq.com + * @since 5.5.8 + */ + +public class RadixUtil { + /** + * 34进制字符串,不包含 IO 字符 + * 对于需要补齐的,自己可以随机填充IO字符 + * 26个字母:abcdefghijklmnopqrstuvwxyz + */ + public final static String RADIXS_34 = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"; + /** + * 打乱后的34进制 + */ + public final static String RADIXS_SHUFFLE_34 = "H3UM16TDFPSBZJ90CW28QYRE45AXKNGV7L"; + + /** + * 59进制字符串,不包含 IOl 字符 + */ + public final static String RADIXS_59 = "0123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"; + /** + * 打乱后的59进制 + */ + public final static String RADIXS_SHUFFLE_59 = "vh9wGkfK8YmqbsoENP3764SeCX0dVzrgy1HRtpnTaLjJW2xQiZAcBMUFDu5"; + /** + * 把一个整型数值转换成自己定义的进制 + * 长度即进制
+ *
  • encode("AB",10) 51转换成2进制,A=0;B=1 。 二进制1010,结果 BABA
  • + *
  • encode("VIP",21) 21转换成3进制,V=0;I=1;P=2 ,三进制210 ,得到结果PIV
  • + * + * @param radixs 自定进制,不要重复,否则转不回来的。 + * @param num 要转换的数值 + * @return 自定义进制字符串 + */ + public static String encode(final String radixs, final int num) { + //考虑到负数问题 + long tmpNum = (num >= 0 ? num : (0x100000000L - (~num + 1))); + + return encode(radixs, num, 32); + } + + /** + * 把一个长整型数值转换成自己定义的进制 + * + * @param radixs 自定进制,不要重复,否则转不回来的。 + * @param num 要转换的数值 + * @return 自定义进制字符串 + */ + public static String encode(final String radixs, final long num) { + if (num < 0) { + throw new RuntimeException("暂不支持负数!"); + } + + return encode(radixs, num, 64); + } + + private static String encode(final String radixs, final long num, int maxLength) { + if (radixs.length() < 2) { + throw new RuntimeException("自定义进制最少两个字符哦!"); + } + //目标是多少进制 + int rl = radixs.length(); + //考虑到负数问题 + long tmpNum = num; + //进制的结果,二进制最小进制转换结果是32个字符 + //StringBuilder 比较耗时 + char[] aa = new char[maxLength]; + //因为反需字符串比较耗时 + int i = aa.length; + do { + aa[--i] = radixs.charAt((int) (tmpNum % rl)); + tmpNum /= rl; + } while (tmpNum > 0); + //去掉前面的字符串,trim比较耗时 + return new String(aa, i, aa.length - i); + } + + /** + * 把转换后的进制字符还原成int 值 + * + * @param radixs 自定进制,需要和encode的保持一致 + * @param encodeStr 需要转换成十进制的字符串 + * @return + */ + public int decodeToInt(final String radixs, final String encodeStr) { + //还原负数 + return (int) decodeToLong(radixs, encodeStr); + } + + /** + * 把转换后进制的字符还原成long 值 + * + * @param radixs + * @param encodeStr + * @return + */ + public long decodeToLong(final String radixs, final String encodeStr) { + //目标是多少进制 + int rl = radixs.length(); + long res = 0L; + + for (char c : encodeStr.toCharArray()) { + res = res * rl + radixs.indexOf(c); + } + return res; + } +}