英文:
Not the same output when using Messagepack encoding on Golang and Rust
问题
我正在尝试让Go服务器与Rust客户端进行通信(反之亦然),为此,我想要序列化(或者在Go中称为Marshal)一个结构体以便发送它。
以下是我的代码:
package main
import (
"fmt"
"github.com/vmihailenco/msgpack/v5"
)
func ExampleMarshal() {
type Human struct {
Age byte
}
var x = Human{Age: 42}
b, err := msgpack.Marshal(x)
if err != nil {
panic(err)
}
fmt.Println("b:", b)
}
func main() {
ExampleMarshal()
} // 参考自 https://github.com/vmihailenco/msgpack
extern crate serde;
#[macro_use]
extern crate rmp_serde as rmps;
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use rmps::{Deserializer, Serializer};
#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct Human {
age: u8,
}
fn main() {
let mut buf = Vec::new();
let val = Human {
age: 42,
};
val.serialize(&mut Serializer::new(&mut buf)).unwrap();
println!("{:?}", buf);
} // 参考自 https://docs.rs/rmp-serde/latest/rmp_serde/
问题是,使用完全相同的值,我得不到相同的序列化值:
- Go -> b: [129 163 65 103 101 204 42]
- Rust -> [145, 42]
有人能解释一下为什么我得不到完全相同的值吗?
我的目标是让Go的输出与Rust的输出相同。
英文:
I am trying to make communicate a Go server with a Rust client (and vice-versa), and to do so, I want to serialize (or Marshal as you would say in Go) a struct in order to send it.
Here are my codes :
package main
import (
"fmt"
"github.com/vmihailenco/msgpack/v5"
)
func ExampleMarshal() {
type Human struct {
Age byte
}
var x = Human{Age: 42}
b, err := msgpack.Marshal(x)
if err != nil {
panic(err)
}
fmt.Println("b:", b)
}
func main () {
ExampleMarshal()
} // took from https://github.com/vmihailenco/msgpack
extern crate serde;
#[macro_use]
extern crate rmp_serde as rmps;
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use rmps::{Deserializer, Serializer};
#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct Human {
age: u8,
}
fn main() {
let mut buf = Vec::new();
let val = Human {
age: 42,
};
val.serialize(&mut Serializer::new(&mut buf)).unwrap();
println!("{:?}", buf);
} // took from https://docs.rs/rmp-serde/latest/rmp_serde/
The problem is that with the exact same values, I don't get the same serialized value
- Go -> b: [129 163 65 103 101 204 42]
- Rust -> [145, 42]
Can someone explain me why I don't get the exact same values ?
My goal is to have the Go Output the same as the Rust one
答案1
得分: 2
我自己的问题的完整答案。
Rust部分是正确的,只有Go部分有一个“问题”,如果我们可以称之为问题的话。
在查找互联网的过程中,我发现应该使用“Compact Encoding”才能得到所需的结果。
解决方案是在golang中导入v4.0.4版本的msgpack,并将UseCompactEncoding标志设置为true。
为了总结这个线程,以下是使用msgpack返回完全相同输出的代码:
use serde::{Deserialize, Serialize};
use rmp_serde::{Deserializer, Serializer};
#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct Human {
name: String,
age: u8,
}
fn main() {
let x = Human { name: "nice".to_string(), age: 69 };
let buf = rmp_serde::to_vec(&x).unwrap();
println!("{:?}", buf);
}
package main
import (
"bytes"
"fmt"
"github.com/vmihailenco/msgpack"
)
func main() {
type Human struct {
Name string
Age uint64
}
var buf bytes.Buffer
enc := msgpack.NewEncoder(&buf).StructAsArray(true).UseCompactEncoding(true)
err := enc.Encode(&Human{Name: "nice", Age: 69})
if err != nil {
panic(err)
}
fmt.Println(buf.Bytes())
}
Golang输出:[146 69 164 110 105 99 101]
Rust输出:[146, 69, 164, 110, 105, 99, 101]
英文:
Full answer for my own question.
The rust part was good, it was only the Go one that had a "problem", if we can call this a problem.
After digging the internet, I have found that I should use "Compact Encoding" in order to have the desired result.
The solution was to import the v4.0.4 version of msgpack in golang, and set to true, the UseCompactEncoding flag.
To conclude this thread, here are the codes that returns the exact same output using msgpack :
use serde::{Deserialize, Serialize};
use rmp_serde::{Deserializer, Serializer};
#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct Human {
name: String,
age: u8,
}
fn main() {
let x = Human { name: "nice".to_string(), age: 69 };
let buf = rmp_serde::to_vec(&x).unwrap();
println!("{:?}", buf);
}
package main
import (
"bytes"
"fmt"
"github.com/vmihailenco/msgpack"
)
func main() {
type Human struct {
Name string
Age uint64
}
var buf bytes.Buffer
enc := msgpack.NewEncoder(&buf).StructAsArray(true).UseCompactEncoding(true)
err := enc.Encode(&Human{Name: "nice", Age: 69})
if err != nil {
panic(err)
}
fmt.Println(buf.Bytes())
}
Golang output : [146 69 164 110 105 99 101]
Rust output: [146, 69, 164, 110, 105, 99, 101]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论