将 protobuf 对象散列为字符串作为 redis 数据库的键
Hash protobuf object to a string as the key for redis database
我有某种复杂的 protobuf 对象。这是发送到我的 GRPC 端点的请求。如果我之前没有处理它,我只想处理它。所以我想将该对象散列为某个字符串并将其存储在我的 Redis 数据库中。我使用 ObjectHash-Proto 但是使用新版本的 protobuf-compiler 我得到了这个错误:
got an unexpected struct of type 'impl.MessageState' for field {Name:state PkgPath:... Type:impl.MessageState Tag: Offset:0 Index:[0] Anonymous:false}
似乎它不支持结构,新版本的 protobuf-compiler 生成包含结构的代码。
我无法为每个请求生成某种 ID。 ID实际上是整个对象的哈希值。
如果您有 proto.Message
[1],那么您将免费获得一个 Marshal 函数 [2]。
因此,在封送消息后,您可以将字节传递给 base64
,或者
md5
或任何你想要的:
package main
import (
"encoding/base64"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/structpb"
)
func hash(m proto.Message) (string, error) {
b, err := proto.Marshal(m)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(b), nil
}
func main() {
m, err := structpb.NewStruct(map[string]interface{}{
"month": 12, "day": 31,
})
if err != nil {
panic(err)
}
s, err := hash(m)
if err != nil {
panic(err)
}
println(s) // ChIKBW1vbnRoEgkRAAAAAAAAKEAKEAoDZGF5EgkRAAAAAAAAP0A=
}
Proto 序列化不稳定,因此您不能依靠对输出进行编组和散列来为同一消息生成相同的散列。
来自https://developers.google.com/protocol-buffers/docs/reference/go/faq#hash
How do I use a protocol buffer message as a hash key?
You need canonical serialization, where the marshaled output of a protocol buffer message is guaranteed to be stable over time. Unfortunately, no specification for canonical serialization exists at this time. You'll need to write your own or find a way to avoid needing one.
我能找到的最接近的解决方案是 deepmind objecthash-proto,但在过去 4 年中没有任何贡献,所以我认为它可能已经过时了
我有某种复杂的 protobuf 对象。这是发送到我的 GRPC 端点的请求。如果我之前没有处理它,我只想处理它。所以我想将该对象散列为某个字符串并将其存储在我的 Redis 数据库中。我使用 ObjectHash-Proto 但是使用新版本的 protobuf-compiler 我得到了这个错误:
got an unexpected struct of type 'impl.MessageState' for field {Name:state PkgPath:... Type:impl.MessageState Tag: Offset:0 Index:[0] Anonymous:false}
似乎它不支持结构,新版本的 protobuf-compiler 生成包含结构的代码。
我无法为每个请求生成某种 ID。 ID实际上是整个对象的哈希值。
如果您有 proto.Message
[1],那么您将免费获得一个 Marshal 函数 [2]。
因此,在封送消息后,您可以将字节传递给 base64
,或者
md5
或任何你想要的:
package main
import (
"encoding/base64"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/structpb"
)
func hash(m proto.Message) (string, error) {
b, err := proto.Marshal(m)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(b), nil
}
func main() {
m, err := structpb.NewStruct(map[string]interface{}{
"month": 12, "day": 31,
})
if err != nil {
panic(err)
}
s, err := hash(m)
if err != nil {
panic(err)
}
println(s) // ChIKBW1vbnRoEgkRAAAAAAAAKEAKEAoDZGF5EgkRAAAAAAAAP0A=
}
Proto 序列化不稳定,因此您不能依靠对输出进行编组和散列来为同一消息生成相同的散列。
来自https://developers.google.com/protocol-buffers/docs/reference/go/faq#hash
How do I use a protocol buffer message as a hash key?
You need canonical serialization, where the marshaled output of a protocol buffer message is guaranteed to be stable over time. Unfortunately, no specification for canonical serialization exists at this time. You'll need to write your own or find a way to avoid needing one.
我能找到的最接近的解决方案是 deepmind objecthash-proto,但在过去 4 年中没有任何贡献,所以我认为它可能已经过时了