在Golang中,你可以通过自定义JSON编码器来实现将字节数组编码为十六进制字符串。这里的关键是使用json.Marshaler接口,但考虑到你的数据是动态的,需要递归处理。以下是一个解决方案:
package main
import (
"encoding/hex"
"encoding/json"
"fmt"
"reflect"
)
// HexMarshaler 递归地将字节切片转换为十六进制字符串
type HexMarshaler struct{}
func (h HexMarshaler) MarshalJSON() ([]byte, error) {
return json.Marshal(h.convertToHex(reflect.ValueOf(h)))
}
func (h HexMarshaler) convertToHex(v reflect.Value) interface{} {
switch v.Kind() {
case reflect.Slice:
if v.Type().Elem().Kind() == reflect.Uint8 {
// 字节切片转换为十六进制字符串
return hex.EncodeToString(v.Bytes())
}
// 递归处理切片元素
result := make([]interface{}, v.Len())
for i := 0; i < v.Len(); i++ {
result[i] = h.convertToHex(v.Index(i))
}
return result
case reflect.Map:
// 递归处理map
result := make(map[string]interface{})
iter := v.MapRange()
for iter.Next() {
key := fmt.Sprintf("%v", iter.Key().Interface())
result[key] = h.convertToHex(iter.Value())
}
return result
case reflect.Interface:
// 处理interface{}类型
if v.IsNil() {
return nil
}
return h.convertToHex(v.Elem())
default:
return v.Interface()
}
}
func main() {
// 示例数据
data := map[string]interface{}{
"address": []byte{0x9c, 0x37, 0xcb, 0x52, 0x94, 0xab, 0xce, 0x70},
"nested": map[string]interface{}{
"tx": []byte{0x77, 0xdf, 0x5b, 0xd7, 0x20, 0xb6, 0xfb, 0x86},
},
"list": []interface{}{
[]byte{0x00, 0x17, 0x7a, 0x56},
"regular string",
42,
},
}
// 使用自定义编码器
marshaled, err := json.Marshal(HexMarshaler{data})
if err != nil {
panic(err)
}
fmt.Println(string(marshaled))
}
对于你的具体数据结构,这里是一个更直接的实现:
func convertToHex(data interface{}) interface{} {
switch v := data.(type) {
case []byte:
return hex.EncodeToString(v)
case []interface{}:
result := make([]interface{}, len(v))
for i, item := range v {
result[i] = convertToHex(item)
}
return result
case map[string]interface{}:
result := make(map[string]interface{})
for key, val := range v {
result[key] = convertToHex(val)
}
return result
case map[interface{}]interface{}:
result := make(map[string]interface{})
for key, val := range v {
result[fmt.Sprintf("%v", key)] = convertToHex(val)
}
return result
default:
return v
}
}
// 使用示例
func main() {
// 假设这是你的CBOR解码结果
cborData := map[interface{}]interface{}{
0: []interface{}{
[]byte{0x9c, 0x37, 0xcb, 0x52, 0x94, 0xab, 0xce, 0x70},
1,
},
1: []interface{}{
[]byte{0x00, 0x17, 0x7a, 0x56, 0xa4, 0x20, 0x2e, 0x7e},
64,
},
}
// 转换为十六进制格式
hexData := convertToHex(cborData)
// 编码为JSON
jsonBytes, err := json.MarshalIndent(hexData, "", " ")
if err != nil {
panic(err)
}
fmt.Println(string(jsonBytes))
}
输出结果中的字节数组会被转换为十六进制字符串:
{
"0": [
"9c37cb5294abce70",
1
],
"1": [
"00177a56a4202e7e",
64
]
}
这种方法通过递归遍历数据结构,将遇到的每个[]byte都转换为十六进制字符串,同时保持其他数据类型不变。这样你就可以在不预定义结构体的情况下,将任意包含字节数组的数据结构编码为十六进制格式的JSON。