1.概要

最近考虑采用protobuf来实现kafka消息传递,所以先测试一下golang和python之前序列化互通问题。

由于go和python对于二进制的表示在ide层面是无法统一的,直接把python的字符串拷出来放到golang肯定是不行的,需要通过hex进行16进制表示法

2.bytes和hex转化语法

Bytes -> Hex string

# Python
my_bytes = bytes([0x06, 0xe5, 0x33, 0xfd, 0x1a, 0xda, 0x86, 0x39,
                  0x1f, 0x3f, 0x6c, 0x34, 0x32, 0x04, 0xb0, 0xd2,
                  0x78, 0xd4, 0xaa, 0xec, 0x1c, 0x0b, 0x20, 0xaa,
                  0x27, 0xba, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00])



# 返回一个字符串,两个十六进制的字符表示一个byte(Return a string object containing two hexadecimal digits for each byte in the instance)
my_hex = my_bytes.hex()


// Golang

my_bytes := []byte{0x79, 0xa6, 0x1a, 0xdb, 0xc6, 0xe5, 0xa2, 0xe1,
                   0x39, 0xd2, 0x71, 0x3a, 0x54, 0x6e, 0xc7, 0xc8,
                   0x75, 0x63, 0x2e, 0x75, 0xf1, 0xdf, 0x9c, 0x3f,
                   0xa6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}

my_hex = hex.EncodeToString(my_bytes)  // 返回十六进制编码字符串

Hex string -> Bytes

# Python:
my_bytes = bytes.fromhex(my_hex)

//  Golang:
my_bytes = hex.DecodeString(my_hex)

 

3.实例

3.1. python protobuf输出hex字符串

python protobuf

from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf import descriptor_pb2

import person_pb2 as Person

person1 = Person.Person()
person1.id = 1234
person1.name = "John Doe"
person1.email = "jdoe@example.com"
phone = person1.phones.add()  # phones字段是符合类型,调用add()方法初始化新实例。如果phones字段是标量类型,直接append()添加新元素即可。
phone.number = "555-4321"
phone.type = Person.Person.HOME

persion1Str = person1.SerializeToString()
print("persion1Str,hex", persion1Str.hex())

输出:

persion1Str,hex 0a084a6f686e20446f6510d2091a106a646f65406578616d706c652e636f6d220c0a083535352d343332311001

得到hex字符串

 

3.2. golang protobuf导入hex字符串

go protobuf

package main

import (
	"encoding/hex"
	"google.golang.org/protobuf/proto"
	"log"
)

func main() {
	var bytes []byte

	hexstr := "0a084a6f686e20446f6510d2091a106a646f65406578616d706c652e636f6d220c0a083535352d343332311001"
	bytes, _ = hex.DecodeString(hexstr)

	person := &Person{}
    if err := proto.Unmarshal(bytes, person); err != nil {
        log.Fatalln("Failed to parse address book:", err)
    }
    fmt.Println(person)
}

输出:

name:"John Doe" id:1234 email:"jdoe@example.com" phones:{number:"555-4321" type:HOME}

测试完成