在使用Messagepack编码时,使用Golang和Rust时输出不一样。

huangapple go评论84阅读模式
英文:

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]

huangapple
  • 本文由 发表于 2022年2月23日 21:20:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/71237712.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定