如何在Java中使用自定义字符集将字节数组编码为Base63字符串
Java自定义字符集Base63编解码实现
我们需要实现支持指定字符集的Base63双向编解码能力,替换JDK不适用的java.util.Base64工具。
约定字符集
指定的63个字符按顺序排列如下:
'0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', '_'
完整工具类代码
import java.math.BigInteger; import java.util.Arrays; public class Base63 { // 自定义字符表,严格按照要求顺序 private static final char[] ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_".toCharArray(); private static final int BASE = ALPHABET.length; // 反向映射表,用于解码 private static final int[] REVERSE_MAP = new int[128]; static { Arrays.fill(REVERSE_MAP, -1); for (int i = 0; i < ALPHABET.length; i++) { REVERSE_MAP[ALPHABET[i]] = i; } } /** * 字节数组编码为Base63字符串 */ public static String encode(byte[] bytes) { if (bytes == null || bytes.length == 0) { return ""; } // 处理前导零,记录前导零个数 int leadingZeros = 0; while (leadingZeros < bytes.length && bytes[leadingZeros] == 0) { leadingZeros++; } if (leadingZeros == bytes.length) { return "0".repeat(leadingZeros); } // 字节数组转大整数处理 BigInteger num = new BigInteger(1, bytes); StringBuilder sb = new StringBuilder(); while (num.compareTo(BigInteger.ZERO) > 0) { BigInteger[] divMod = num.divideAndRemainder(BigInteger.valueOf(BASE)); sb.append(ALPHABET[divMod[1].intValue()]); num = divMod[0]; } // 补回前导零 sb.append("0".repeat(leadingZeros)); // 反转得到正确顺序 return sb.reverse().toString(); } /** * Base63字符串解码为字节数组 */ public static byte[] decode(String base63Str) { if (base63Str == null || base63Str.isEmpty()) { return new byte[0]; } // 处理前导零 int leadingZeros = 0; while (leadingZeros < base63Str.length() && base63Str.charAt(leadingZeros) == '0') { leadingZeros++; } if (leadingZeros == base63Str.length()) { byte[] result = new byte[leadingZeros]; Arrays.fill(result, (byte) 0); return result; } // 字符串转大整数 BigInteger num = BigInteger.ZERO; for (int i = leadingZeros; i < base63Str.length(); i++) { char c = base63Str.charAt(i); if (c >= REVERSE_MAP.length || REVERSE_MAP[c] == -1) { throw new IllegalArgumentException("非法Base63字符: " + c); } num = num.multiply(BigInteger.valueOf(BASE)).add(BigInteger.valueOf(REVERSE_MAP[c])); } // 转字节数组,去掉BigInteger自带的符号位 byte[] numBytes = num.toByteArray(); if (numBytes[0] == 0) { numBytes = Arrays.copyOfRange(numBytes, 1, numBytes.length); } // 补回前导零 byte[] result = new byte[leadingZeros + numBytes.length]; Arrays.fill(result, 0, leadingZeros, (byte) 0); System.arraycopy(numBytes, 0, result, leadingZeros, numBytes.length); return result; } }
使用验证示例
给出的测试用例可直接运行通过:
public class Test { public static void main(String[] args) { byte[] byteArray = new byte[]{0,1,2,3,4,5,-1,-2,-3}; String base63String = Base63.encode(byteArray); byte[] decodedByteArray = Base63.decode(base63String); assert java.util.Arrays.equals(byteArray, decodedByteArray); System.out.println("编解码验证通过"); } }
内容的提问来源于stack exchange,提问作者Oleksandr
相关产品推荐
相关产品推荐

