You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将整数编码为可作为URL参数值的可逆字符串(Java/JSF)

解决方案:把企业ID转成可逆的URL安全短字符串

针对你的需求——把整数企业ID转成能还原、URL可用、长度适中的字符串,避免被轻易枚举所有企业,给你几个实用的方案,都是Java/JSF环境下能直接用的:

一、自定义进制转换(最省事的方案)

核心想法就是把整数ID转换成自定义的高进制(比如64进制),用URL安全的字符当进制符号。这种方法完全可逆,生成的字符串还特别短。

代码示例(Java)

  1. 先定义一套URL安全的字符集,比如包含大小写字母、数字、-和_(这俩在URL里不用编码):
private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
  1. 写ID转字符串的方法:
public static String encode(long id) {
    if (id == 0) {
        return String.valueOf(ALPHABET.charAt(0));
    }
    StringBuilder sb = new StringBuilder();
    while (id > 0) {
        sb.append(ALPHABET.charAt((int) (id % ALPHABET.length())));
        id = id / ALPHABET.length();
    }
    return sb.reverse().toString();
}
  1. 再写字符串转回ID的方法:
public static long decode(String code) {
    long id = 0;
    for (char c : code.toCharArray()) {
        id = id * ALPHABET.length() + ALPHABET.indexOf(c);
    }
    return id;
}

额外优化:加盐防枚举

要是怕有人瞎猜字符串试所有企业ID,可以给ID加个盐再转换——比如转之前先和一个固定的长整数异或:

// 编码时
long saltedId = originalId ^ 123456789L;
String code = encode(saltedId);

// 解码时
long saltedId = decode(code);
long originalId = saltedId ^ 123456789L;

这样就算别人解码出数值,也不是真实的企业ID,得知道盐才能拿到正确值,大大增加枚举难度。

二、加密式可逆转换(安全性更高)

如果需要更强的安全性,不想让任何人能反向推导出ID,就用对称加密(比如AES),把加密后的字节转成URL安全的Base64格式。

代码示例(Java)

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class IdEncryptor {
    // 用16字节的密钥(AES-128),自己换个安全的密钥存好
    private static final byte[] AES_KEY = "YourSecureKey123".getBytes();
    private static final String ALGORITHM = "AES";

    public static String encrypt(long companyId) throws Exception {
        SecretKeySpec keySpec = new SecretKeySpec(AES_KEY, ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);
        
        byte[] encryptedBytes = cipher.doFinal(String.valueOf(companyId).getBytes());
        // 用URL安全的Base64,去掉多余的=符号
        return Base64.getUrlEncoder().withoutPadding().encodeToString(encryptedBytes);
    }

    public static long decrypt(String encryptedCode) throws Exception {
        SecretKeySpec keySpec = new SecretKeySpec(AES_KEY, ALGORITHM);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, keySpec);
        
        byte[] decodedBytes = Base64.getUrlDecoder().decode(encryptedCode);
        byte[] decryptedBytes = cipher.doFinal(decodedBytes);
        return Long.parseLong(new String(decryptedBytes));
    }
}

注意点

  • 密钥一定要妥善保管,丢了的话所有加密后的字符串都没法还原了
  • 加密后的字符串长度会比进制转换的长一些,比如ID=5可能转成16位左右的字符串

三、现成工具库(不想自己写代码的话)

  • Apache Commons Codec:提供现成的URL安全Base64编码,你可以配合自己的加密/进制转换逻辑用
  • ShortUUID:虽然主要用来生成UUID,但也支持自定义字符集和可逆转换,不过对于整数ID来说,自定义进制还是更简单直接

四、在JSF里怎么用

把上面的工具类做成CDI Bean,就能在JSF的Managed Bean里直接调用了:

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;

@Named
@ApplicationScoped
public class CompanyIdConverter {
    private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
    private static final long SALT = 987654321L;

    public String encodeCompanyId(long id) {
        long saltedId = id ^ SALT;
        return encode(saltedId);
    }

    public long decodeCompanyId(String code) {
        long saltedId = decode(code);
        return saltedId ^ SALT;
    }

    // 这里放上面的encode和decode私有方法
    private String encode(long id) {
        // 实现代码
    }

    private long decode(String code) {
        // 实现代码
    }
}

然后在处理登录请求的Bean里获取参数并转换:

import javax.inject.Inject;
import javax.faces.bean.ManagedBean;

@ManagedBean
public class LoginBean {
    @Inject
    private CompanyIdConverter companyIdConverter;

    public void initLogin() {
        String ociParam = FacesContext.getCurrentInstance().getExternalContext()
                .getRequestParameterMap().get("OCI");
        if (ociParam != null) {
            long companyId = companyIdConverter.decodeCompanyId(ociParam);
            // 拿到真实企业ID后,做后续的品牌加载、登录逻辑
        }
    }
}

内容的提问来源于stack exchange,提问作者Kevin Rahe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 14:52:32