2017-08-26 46 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

相關問題