我取一段数据并将其放在 GO 和 JS 中的 protobuf 中,然后在每个平台上对 PB 进行编码,得到的序列化值不同。由于我们使用编码值进行签名和散列,因此它们匹配至关重要。据我所知,我认为不同之处在于 JS 在编码输出中包含默认值,而 GO 没有。
两个平台都从同一段 JSON 开始。这是GO:
listing := new(pb.Listing)
err = jsonpb.UnmarshalString(string(jsonListing), listing)
ser, err := proto.Marshal(listing)
sEnc := b64.StdEncoding.EncodeToString(ser)
来自 GO 的 base64 编码值为:
ChR0ZXN0LXRlc3QtdGVzdC1taWxseRLEAQouUW1RMlRoQkw2emNZeEJzQ0gyZlVWM0VVaVBNM3RZbWRuUDNxN2prZTIxdUJNcBpJCiQIARIg1JRiC99XTy49u47TrmPhebH2IoWanvr9rfG2+cj8O4YSIQLJRSKlbpvhAB4nyf2yr0gTbVTXwn8uL41usco/cwtyliJHMEUCIQDqnEyTrFKKNY0FRlbn9wC4+69ozF8C3meKcLQG36nseQIgfJs1dJdFTSM2lGg7hQ68O1PVjAZHWO2XRaogo3OMeUgaKwgEIgYI4LSc/wcqA0xUQyoDQlRDKgNCQ0gqA1pFQzIDVVNEQLgIUIDC1y8ioAIKFFRFU1QgVEVTVCBURVNUIG1pbGx5IGQ6/gEKDG11cmFrYW1pLmpwZxIuUW1WeVZIOFJhbTZNZTNpaHlLZ2p6SnNNMlhaeG5QajZQS1NmbmVSRmY4WmFhRBouUW1laFFoMlNDeVZuWXpZNTduVFAzOWRrbUU3Z0t5ekpHeUhUTko0dXpDM2QyRCIuUW1YcTFSTEt0d2E3VmNSemFhN0dTWEtoVWdIYnBicUhNZWhVS2RDeVVTV1hvNyouUW1VeHlBdHYzdzgxWVFnaEFtckVHTThpbjRYU01QNkROZEVnY1RqNm12UXRjMzIuUW1TODhUcVgySzlwU1VvdnFjczNXbkdhUDFRQjdoTXNSUHdMZFVXNmR5UzRoTFIDTkVXYgAqKQoMVVNBIHNoaXBzdGVyEAEaAuoBKhMKCFN0YW5kYXJkEBkaAzUtNyAK
下面是 JS 的作用:
const ListingPB = getProtoContractsRoot().lookupType('Listing');
const listingPB = ListingPB.fromObject(jsonListing);
const ser = ListingPB
.encode(listingPB)
.finish();
结果是:
ChR0ZXN0LXRlc3QtdGVzdC1taWxseRLGAQouUW1RMlRoQkw2emNZeEJzQ0gyZlVWM0VVaVBNM3RZbWRuUDNxN2prZTIxdUJNcBIAGkkKJAgBEiDUlGIL31dPLj27jtOuY+F5sfYihZqe+v2t8bb5yPw7hhIhAslFIqVum+EAHifJ/bKvSBNtVNfCfy4vjW6xyj9zC3KWIkcwRQIhAOqcTJOsUoo1jQVGVuf3ALj7r2jMXwLeZ4pwtAbfqex5AiB8mzV0l0VNIzaUaDuFDrw7U9WMBkdY7ZdFqiCjc4x5SBo6CAQQABgAIggI4LSc/wcQACoDTFRDKgNCVEMqA0JDSCoDWkVDMgNVU0Q6AEC4CEoAUIDC1y9dAAAAACKxAgoUVEVTVCBURVNUIFRFU1QgbWlsbHkSABoAIGQoADr+AQoMbXVyYWthbWkuanBnEi5RbVZ5Vkg4UmFtNk1lM2loeUtnanpKc00yWFp4blBqNlBLU2ZuZVJGZjhaYWFEGi5RbWVoUWgyU0N5Vm5Zelk1N25UUDM5ZGttRTdnS3l6Skd5SFROSjR1ekMzZDJEIi5RbVhxMVJMS3R3YTdWY1J6YWE3R1NYS2hVZ0hicGJxSE1laFVLZEN5VVNXWG83Ki5RbVV4eUF0djN3ODFZUWdoQW1yRUdNOGluNFhTTVA2RE5kRWdjVGo2bXZRdGMzMi5RbVM4OFRxWDJLOXBTVW92cWNzM1duR2FQMVFCN2hNc1JQd0xkVVc2ZHlTNGhMTQAAAABSA05FV2IGEgAYACAAKikKDFVTQSBzaGlwc3RlchABGgLqASoTCghTdGFuZGFyZBAZGgM1LTcgCkoAUgA=
...这与 GO 提出的不同。
如果我将这两个 base64 字符串都带入 JS,将它们解码为 PB,然后toJSON()
将 PB 解码并查看两个对象的差异,看起来不同之处在于 JS 正在序列化默认值而 GO 不是(JS 开启正确的)。
我试过这样序列化 JS,但结果是一样的:
const ser =
ListingPB
.encode(ListingPB.toObject(listingPB, { defaults: false }))
.finish();
那么,有什么方法可以使两个平台之间的输出保持一致?原始 JSON 输入是相同的,但输出的结果不同。