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

Go语言字符串加密解密异常:加密后解密结果不符问题排查

问题分析与解决方案

你遇到的核心问题是加密和解密的处理逻辑完全不匹配,导致解密时处理的根本不是加密后的原始字节数据。

为什么会出错?

  • 你的Encrypt函数把每个异或后的字节,转换成了十六进制转义字符串格式(比如一个字节0xcd会被格式化为字符串\xcd,这是4个独立的ASCII字符:\、x、c、d)。
  • 但Decrypt函数却直接拿这个转义字符串的每个字符(也就是上述4个字符的ASCII值)去和密钥异或,相当于你在解密一堆和原始加密字节完全无关的字符数据,结果自然和原字符串不符。

修正方案(两种可选)

方案一:直接处理原始字节(推荐,更高效简洁)

放弃转义字符串的输出,让加密后的结果直接是异或后的字节组成的字符串(Go中string本质就是字节序列),这样加密和解密逻辑对称:

package main
import (
 "fmt"
)
const key = "\xbd\xb2\x3d\xbc\x20\xe2\x8c\x98" // 你的密钥
func Encrypt(input string) (output string) {
 keyLen := len(key)
 for i := 0; i < len(input); i++ {
  output += string(input[i] ^ key[i%keyLen])
 }
 return
}
func Decrypt(input string) (output string) {
 keyLen := len(key)
 for i := 0; i < len(input); i++ {
  output += string(input[i] ^ key[i%keyLen])
 }
 return
}
func main() {
 stringa := "password"
 encrypted := Encrypt(stringa)
 fmt.Printf("加密后(原始字节,带转义显示):%q\n", encrypted)
 decrypted := Decrypt(encrypted)
 fmt.Println("解密后:", decrypted)
 fmt.Println("原字符串:", stringa)
}

运行后会输出匹配的结果,%q格式化符会帮你把不可打印的字符转义显示,方便查看。

方案二:保留转义字符串输出,先解析再解密

如果你必须输出\xXX格式的转义字符串,那解密时需要先把这个字符串解析回原始的加密字节数组,再进行异或操作:

package main
import (
 "fmt"
 "strconv"
)
const key = "\xbd\xb2\x3d\xbc\x20\xe2\x8c\x98" // 你的密钥
func Encrypt(input string) (output string) {
 keyLen := len(key)
 for i := 0; i < len(input); i++ {
  output += fmt.Sprintf("\\x%02x", input[i]^key[i%keyLen])
 }
 return
}
func Decrypt(input string) (output string, err error) {
 // 给转义字符串加上双引号,让strconv.Unquote能正确解析转义序列
 quotedInput := `"` + input + `"`
 rawEncryptedBytes, err := strconv.Unquote(quotedInput)
 if err != nil {
  return "", fmt.Errorf("解析转义字符串失败:%w", err)
 }

 // 用解析后的原始字节进行解密
 keyLen := len(key)
 for i := 0; i < len(rawEncryptedBytes); i++ {
  output += string(rawEncryptedBytes[i] ^ key[i%keyLen])
 }
 return output, nil
}
func main() {
 stringa := "password"
 encrypted := Encrypt(stringa)
 fmt.Println("加密后:", encrypted)
 decrypted, err := Decrypt(encrypted)
 if err != nil {
  fmt.Println("解密错误:", err)
  return
 }
 fmt.Println("解密后:", decrypted)
 fmt.Println("原字符串:", stringa)
}

这个方案中,strconv.Unquote会把\xcd这样的转义序列转换成对应的单个字节0xcd,之后再用密钥异或就能得到原字符串了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:17:09