Golang中是否可以实现ByteArrayInString编码?
Golang中是否可以实现ByteArrayInString编码?
我正在尝试将一个名为 ByteArrayInString 的替代 Base64 编码移植到 Go 语言中。
我已经找到了 Java 版本和原始的 C# 代码,将逻辑转换为 Go 是相当容易的。
我遇到的问题是编写一个等效的 单元测试。
问题似乎在于将 []byte 转换为 string 时,它没有将每个字节渲染为一个字符,而是试图将它们转换为 Unicode,从而跳过了编码的字符。
这个练习的全部目的是获得一个仅包含 ASCII 的字符串。如果必须将每个 byte 转换为多字节的 rune 来组成 string,那就有点偏离初衷了。
我遗漏了什么?
以下是我尝试移植代码的 Gist 链接:ByteArrayInString
以及 测试工具。
更多关于Golang中是否可以实现ByteArrayInString编码?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
(帖子已被作者撤回,除非被标记,否则将在24小时后自动删除)
更多关于Golang中是否可以实现ByteArrayInString编码?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在 Go 中实现 ByteArrayInString 编码的关键在于正确处理 ASCII 字符集。你遇到的问题是将 []byte 直接转换为 string 时,Go 会将其解释为 UTF-8 编码的字节序列,而不是原始的字节值。以下是解决方案和示例代码:
// 编码函数
func EncodeToString(data []byte) string {
var buf strings.Builder
buf.Grow(len(data))
for _, b := range data {
// 将字节转换为对应的 ASCII 字符
if b >= 32 && b <= 126 && b != '\\' && b != '\'' && b != '"' {
buf.WriteByte(b)
} else {
// 转义非打印字符
buf.WriteByte('\\')
buf.WriteByte(hexDigit(b >> 4))
buf.WriteByte(hexDigit(b & 0x0F))
}
}
return buf.String()
}
func hexDigit(b byte) byte {
if b < 10 {
return '0' + b
}
return 'A' + (b - 10)
}
// 解码函数
func DecodeString(s string) ([]byte, error) {
result := make([]byte, 0, len(s))
for i := 0; i < len(s); i++ {
c := s[i]
if c == '\\' && i+2 < len(s) {
// 处理转义序列
hi := hexValue(s[i+1])
lo := hexValue(s[i+2])
if hi < 0 || lo < 0 {
return nil, fmt.Errorf("invalid hex escape at position %d", i)
}
result = append(result, byte(hi<<4|lo))
i += 2
} else {
result = append(result, c)
}
}
return result, nil
}
func hexValue(c byte) int {
switch {
case '0' <= c && c <= '9':
return int(c - '0')
case 'A' <= c && c <= 'F':
return int(c - 'A' + 10)
case 'a' <= c && c <= 'f':
return int(c - 'a' + 10)
}
return -1
}
单元测试示例:
func TestByteArrayInString(t *testing.T) {
testCases := []struct {
name string
input []byte
expected string
}{
{
name: "ASCII printable",
input: []byte("Hello World"),
expected: "Hello World",
},
{
name: "With null byte",
input: []byte{0, 1, 2, 'A', 'B', 'C'},
expected: "\\00\\01\\02ABC",
},
{
name: "Mixed characters",
input: []byte("Test\x07\x08\x09"),
expected: "Test\\07\\08\\09",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// 测试编码
encoded := EncodeToString(tc.input)
if encoded != tc.expected {
t.Errorf("EncodeToString() = %q, want %q", encoded, tc.expected)
}
// 测试解码
decoded, err := DecodeString(encoded)
if err != nil {
t.Errorf("DecodeString() error = %v", err)
}
if !bytes.Equal(decoded, tc.input) {
t.Errorf("DecodeString() = %v, want %v", decoded, tc.input)
}
})
}
}
关键点说明:
- Go 的
string是 UTF-8 编码的,直接转换[]byte会进行 UTF-8 解释 - 需要手动处理每个字节,将可打印 ASCII 字符直接写入,非打印字符使用转义序列
- 使用
strings.Builder高效构建结果字符串 - 解码时需要正确处理转义序列
\XX(十六进制表示)
这种实现确保了输出字符串只包含 ASCII 字符,符合 ByteArrayInString 编码的设计目标。

