Golang实现JS的hex转base64功能输出结果不一致如何解决
问题排查结果
核心原因
- 编码逻辑差异:JS的
btoa方法会将输入字符串视为单字节的Latin-1编码,每个字符直接对应1个原始字节;而Go的string默认使用UTF-8编码,你原有代码中将十六进制解析出的数值转成rune再拼接为字符串时,数值大于127的字节会被编码为多字节UTF-8序列,最终转[]byte时和原始字节完全不一致,导致base64编码结果错误。 - 冗余逻辑:JS中的正则操作本质是将十六进制字符串按每两位拆分转为字节,Go标准库已有现成的
encoding/hex包可直接完成该操作,不需要自行用正则处理。
修复方案
方案1:使用标准库实现(推荐)
直接用Go内置的十六进制解码方法,逻辑和JS完全对齐,性能更高也不会出错:
import ( "encoding/base64" "encoding/hex" ) hexToBase64 := func(input string) string { bytes, err := hex.DecodeString(input) if err != nil { panic(err) } return base64.StdEncoding.EncodeToString(bytes) }
传入测试值8953bed713db2113b8e8215b444b7d3e4bca6c139d3d54bb77f8cf7f07ca5482后,输出结果为iVO+1xPbIRO46CFbREt9PkvKbBOdPVS7d/jPfwfKVII=,和JS输出完全一致。
方案2:修改原有逻辑
如果要保留你原来的正则处理逻辑,只需要把字符串拼接改为直接存储字节即可:
import ( "regexp" "strings" "strconv" "encoding/base64" ) hexToBase64 := func(input string) string { x := regexp.MustCompile(`\r|\n`).ReplaceAllString(input, "") x1 := regexp.MustCompile(`([\da-fA-F]{2}) ?`).ReplaceAllString(x, "0x$1 ") x2 := regexp.MustCompile(` +$`).ReplaceAllString(x1, "") x3 := strings.Split(x2, " ") // 改用字节切片存储原始值,避免UTF-8编码问题 var bytes []byte for _, v := range x3 { v = strings.Replace(v, "0x", "", -1) i, e := strconv.ParseUint(v, 16, 8) if e != nil { panic(e) } bytes = append(bytes, byte(i)) } return base64.StdEncoding.EncodeToString(bytes) }
内容的提问来源于stack exchange,提问作者QGX
相关产品推荐
相关产品推荐

