我正在使用必须为non-repudiable的JSON数据。
授予我这些数据的API也有一项服务来验证数据最初来自它们。
As best as I can tell,他们这样做是要求他们最初发送的完整JSON需要在另一个JSON请求中提供给他们,没有字节更改。
我似乎无法保留原始的JSON!
因为我无法修改原始JSON,所以在解组时我已将其小心地保存为json.RawMessage
:
// struct I unmarshal my original data into
type SignedResult struct {
Raw json.RawMessage `json:"random"`
Signature string `json:"signature"`
...
}
// struct I marshal my data back into
type VerifiedSignatureReq {
Raw json.RawMessage `json:"random"`
Signature string `json:"signature"`
}
// ... getData is placeholder for function that gets my data
response := SignedResult{}
x, _ := json.Unmarshal(getData(), &response)
// do some post-processing with SignedResult that does not alter `Raw` or `Signature`
// trouble begins here - x.Raw started off as json.RawMessage...
y := json.Marshal(VerifiedSignatureReq{Raw: x.Raw, Signature: x.Signature}
// but now y.Raw is base64-encoded.
问题在于[]bytes
/ RawMessages
are base64-encoded when marshaled。所以我不能使用这种方法,因为它完全改变了字符串。
我不确定如何确保正确保留此字符串。我假设我的结构中的json.RawMessage
规范可以在编组已经编组的实例的危险中继续存在,因为它实现了Marshaler
接口,但我看起来错了。
我的下一次尝试是尝试:
// struct I unmarshal my original data into
type SignedResult struct {
Raw json.RawMessage `json:"random"`
Signature string `json:"signature"`
...
}
// struct I marshal my data back into
type VerifiedSignatureReq {
Raw map[string]interface{} `json:"random"`
Signature string `json:"signature"`
}
// ... getData is placeholder for function that gets my data
response := SignedResult{}
x, _ := json.Unmarshal(getData(), &response)
// do some post-processing with SignedResult that does not alter `Raw` or `Signature`
var object map[string]interface{}
json.Unmarshal(x.Raw, &object)
// now correctly generates the JSON structure.
y := json.Marshal(VerifiedSignatureReq{Raw: object, Signature: x.Signature}
// but now this is not the same JSON string as received!
这种方法的问题在于数据之间的间距存在微小的字节差异。 cat
到文件时,它看起来不再完全相同。
我无法使用string(x.Raw)
,因为它在使用\
封送时会转义某些字符。
答案 0 :(得分:0)
您需要一个带有自己的封送程序的自定义类型,而不是json.RawMessage
来使用VerifiedSignatureReq
结构。例如:
type VerifiedSignatureReq {
Raw RawMessage `json:"random"`
Signature string `json:"signature"`
}
type RawMessage []byte
func (m RawMessage) MarshalJSON() ([]byte, error) {
return []byte(m), nil
}