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

RC4算法编码异常求助:加密解密字符乱码与失真

解决RC4加密的编码失真问题

问题根源

RC4加密输出的是任意二进制字节流,直接将其转换为String时,无论使用UTF-8、ISO-8859-1还是ASCII编码,都会因为部分字节无法映射为合法字符导致信息丢失:

  • ASCII仅支持0-127范围的字节,非ASCII字符(如法语é、中文)会被截断或替换
  • UTF-8对非法字节序列会替换为�(问号),解密时无法还原原始数据
  • ISO-8859-1虽能覆盖0-255字节,但会出现大量不可打印乱码,且在文本传输/存储中可能被篡改

解决方案:用Base64封装加密结果

把加密后的二进制字节转成Base64编码的字符串,Base64仅使用64个可打印ASCII字符,完全保留二进制信息,彻底解决编码失真问题。流程如下:

  1. 明文String → UTF-8字节数组 → RC4加密 → Base64编码为密文String
  2. 密文String → Base64解码为字节数组 → RC4解密 → UTF-8解码为明文String

修改后的代码示例

RC4核心类(保持字节数组操作逻辑)

public class RC4 {
    private final byte[] S = new byte[256];
    private final byte[] T = new byte[256];
    private final int keylen;

    public RC4(byte[] key) {
        keylen = key.length;
        for (int i = 0; i < 256; i++) {
            S[i] = (byte) i;
            T[i] = key[i % keylen];
        }
        int j = 0;
        byte temp;
        for (int i = 0; i < 256; i++) {
            j = (j + S[i] + T[i]) & 0xFF;
            temp = S[i];
            S[i] = S[j];
            S[j] = temp;
        }
    }

    // 加密:字节数组转字节数组
    public byte[] encrypt(byte[] plaintext) {
        byte[] ciphertext = new byte[plaintext.length];
        int i = 0, j = 0, k;
        byte temp;
        for (int m = 0; m < plaintext.length; m++) {
            i = (i + 1) & 0xFF;
            j = (j + S[i]) & 0xFF;
            temp = S[i];
            S[i] = S[j];
            S[j] = temp;
            k = (S[i] + S[j]) & 0xFF;
            ciphertext[m] = (byte) (plaintext[m] ^ S[k]);
        }
        return ciphertext;
    }

    // RC4解密与加密逻辑完全一致
    public byte[] decrypt(byte[] ciphertext) {
        return encrypt(ciphertext);
    }
}

主类(加入Base64编码解码)

import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class RC4Demo {
    public static void main(String[] args) {
        String key = "demoKey123";
        String plaintext = "stack 测试 法语文本:éàùç";

        // 加密流程
        RC4 rc4Encrypt = new RC4(key.getBytes(StandardCharsets.UTF_8));
        byte[] plainBytes = plaintext.getBytes(StandardCharsets.UTF_8);
        byte[] cipherBytes = rc4Encrypt.encrypt(plainBytes);
        String ciphertext = Base64.getEncoder().encodeToString(cipherBytes);
        System.out.println("加密密文(Base64):" + ciphertext);

        // 解密流程
        RC4 rc4Decrypt = new RC4(key.getBytes(StandardCharsets.UTF_8));
        byte[] decodedCipher = Base64.getDecoder().decode(ciphertext);
        byte[] decryptedBytes = rc4Decrypt.decrypt(decodedCipher);
        String decryptedText = new String(decryptedBytes, StandardCharsets.UTF_8);
        System.out.println("解密明文:" + decryptedText);
    }
}

关键注意事项

  • 统一使用UTF-8进行字符串与字节数组的转换,确保支持所有Unicode字符(包括多语言文本)
  • Base64编码后的密文长度会比原始字节流增加约1/3,但完全避免了编码失真问题
  • 解密时必须使用与加密相同的密钥和编码方式,否则无法正确还原明文

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:32:47