2017-08-26 48 views
2

在我的项目中,我们有一个API,许多客户端可能会向这个API发送事务。应该签署交易。客户端可以用任何语言(C++,C#,python,go,任何)编写,具有任何CPU架构和字节序。针对不同的语言是否有稳定的序列化方法?

现在的问题是将我们的事务模型序列化为字节,以便能够签名并发送它。


我们的团队为此选择了protobuf v3.3.0(proto syntax = proto3)。

我们想用信封图案,看起来像:

message SignedTransaction { 
    message Transaction {/* any data that should be signed */} 
    Transaction transaction = 1; 
    Signature signature = 2; 
} 

签,我们只序列化对象内部交易:

Transaction tx = <...>; 
std::string bytes = tx.SerializeAsString(); 
// and then sign bytes 

与protobuf的现在的问题是,它似乎对于不同的语言来说是不确定的。今天,我们编写了简单的原始文件,其中包含几个整数和字符串,并填充了相同的数据,将其序列化为不同的语言并观察结果。

我们尝试的JavaScript,C++,Java中,斯威夫特和事实证明,除了C++都产生相同的输出字符串:

的JavaScript,Java中,斯威夫特生产:08B90A10BA0A1A106C6F6C206B656B20636865627572656B

C++制作:8FFFFFFB9A10FFFFFFBAA1A106C6F6C206B656B20636865627572656B

C++ parseFromString(str)能够从其他语言反序列化字符串,但反之亦然。

的问题是:

  1. 为什么C++的protobuf产生不同的字符串?
  2. 我们可以为我们的用例使用哪些库?

详情:

// test.proto: 
syntax = "proto3"; 
package api; 

message Msg { 
    uint32 a = 1; 
    int32 b = 2; 
    string c = 3; 
    bytes d = 4; 
} 

// test.cpp: 
api::Msg msg; 

msg.set_a(1337); 
msg.set_b(1338); 
msg.set_c("lol kek cheburek"); 

std::string str = msg.SerializeAsString(); 
// str = 8FFFFFFB9A10FFFFFFBAA1A106C6F6C206B656B20636865627572656B 
+0

我认为一种很好的通用序列化方法是JSON。但当然,它不是一种二进制格式,它是一种文本格式。 –

+0

向图书馆或其他非现场资源提出建议是SO的主题。 – tambre

+0

有什么不对。以更长的代码方式显示您使用的。 Protobuf和这个类中的一些协议,在语言之间工作得很好(我认为问题对于像Marcin所说的C语言没有任何意义) –

回答

0

事实证明,我打印的十六进制字符串的代码有bug。 details

短的答案: 的Protobuf是一种稳定的序列化方法和可以用于描述使用情况。

1

what is serialization

我想的protobuf与术语混淆系列化。 protobuf做的是一种特殊的编码。这除了

我怀疑没有设置b会导致问题。这意味着b的值是未初始化的。 java对象被自动初始化为零,C++对象没有自动初始化,这意味着内容可能只是随机值。并可能发生b

+0

可以同意您更改的答案(主要是) –

+0

而不是链接到维基百科文章,您应该链接现场资源或自己给出简要说明。正如你应该知道的那样,强烈不鼓励链接到非现场资源。 – tambre

相关问题