如何用Java将加密链接的编码字符缩短至5字符以内?
缩短加密链接至5字符以内的解决方案
核心思路
当前直接对原始内容做AES加密+Base64+URL编码的方案,必然导致字符过长(AES块大小为16字节,Base64编码后至少24字符,URL编码后长度进一步增加)。要压缩到5字符以内,必须放弃直接加密编码的思路,改用短码映射机制:
- 将需要传递的原始内容(IMEI/序列号+标识)与唯一短码做关联,存储在后端数据库或缓存中
- 前端仅传递该短码,后端通过短码反向查询得到原始内容,再执行后续业务逻辑
5字符短码若使用大小写字母+数字(共62种可选字符),可覆盖62^5=9亿+的映射量,完全满足常规业务场景需求。
代码修改示例
1. 新增短码生成与映射存储工具
import org.apache.commons.lang3.RandomStringUtils; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; // 生产环境建议用Redis或数据库替代内存Map,支持分布式与持久化 public class ShortCodeMapping { private static final Map<String, String> SHORT_CODE_MAP = new ConcurrentHashMap<>(); private static final int SHORT_CODE_LENGTH = 5; private static final String CODE_CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; // 生成唯一短码并存储映射关系 public static String generateAndSaveShortCode(String originalContent) { String shortCode; // 确保短码唯一 do { shortCode = RandomStringUtils.random(SHORT_CODE_LENGTH, CODE_CHARSET); } while (SHORT_CODE_MAP.containsKey(shortCode)); SHORT_CODE_MAP.put(shortCode, originalContent); return shortCode; } // 通过短码获取原始内容 public static String getOriginalContent(String shortCode) { return SHORT_CODE_MAP.get(shortCode); } }
2. 修改原有业务逻辑代码
private Map<String, Object> getEUGenericDataMapFields(Map<String, Object> data , Document doc) { String imeiOrSerial = org.apache.commons.lang3.StringUtils.isNotBlank(doc.getIMEINumber()) ? doc.getIMEINumber() : doc.getDeviceSerialNo(); String originalContent = imeiOrSerial + PolicyConstants.REGEX_PIPE + PolicyConstants.RENEWAL_SMS; // 替换原加密逻辑为短码生成 String shortCode = ShortCodeMapping.generateAndSaveShortCode(originalContent); // 短码字符均为URL安全格式,无需额外编码 data.put(PolicyConstants.DATA_LINK, shortCode); return data; }
3. 后端接收短码的处理逻辑
当前端传递短码后,反向查询还原原始内容:
// 示例:处理前端传入的短码 public void processShortCode(String shortCode) { String originalContent = ShortCodeMapping.getOriginalContent(shortCode); if (originalContent == null) { // 处理无效短码场景 throw new IllegalArgumentException("Invalid short code"); } // 拆分原始内容,执行原有业务逻辑 String[] contentParts = originalContent.split(PolicyConstants.REGEX_PIPE); String imeiOrSerial = contentParts[0]; String businessType = contentParts[1]; // ... 后续业务操作 }
生产环境注意事项
- 避免用内存Map存储映射,建议使用Redis(可设置过期时间清理无效数据)或数据库,支持分布式部署
- 若需保障数据安全性,可先对原始内容加密再存储,短码仅作为查询密钥,不影响前端传递的短码长度
- 业务量极大时,建议用自增ID转62进制的方式生成短码,比随机生成更高效且无碰撞风险
内容的提问来源于stack exchange,提问作者Sham
相关产品推荐
相关产品推荐

