Json Go相当于Perl5UTF::decode

Json Go相当于Perl5UTF::decode,json,go,unicode,utf-8,Json,Go,Unicode,Utf 8,在Go中,这个Perl程序的等价物是什么 use utf8; my $bin = "..."; # the data may came from file, network, etc utf8::decode( $bin ); # Encode::decode( 'UTF-8', $bin ) also works 定义于 我尝试了几种形式的转换/规范化/转换为字节/符文等,但没有成功 背景: 我使用Sereal()来序列化NoSQL数据库中的一些数据结构,首先我们有一个Perl5.12.2版

在Go中,这个Perl程序的等价物是什么

use utf8;
my $bin = "..."; # the data may came from file, network, etc
utf8::decode( $bin ); # Encode::decode( 'UTF-8', $bin ) also works
定义于

我尝试了几种形式的转换/规范化/转换为字节/符文等,但没有成功

背景:

我使用Sereal()来序列化NoSQL数据库中的一些数据结构,首先我们有一个Perl5.12.2版本,我们使用Go。Sereal格式是二进制的

然而,不知何故,一些perl程序在最后一个BLOB上进行了额外的JSON编码/解码(以UTF-8字符串形式),因此perl程序读写数据是可以的,但当Go尝试解码时,它不起作用

当然,最好的解决方案是停止这种双重编码,但由于我们的数据库中有使用这种格式的条目,我想看看是否可以尝试对其进行解码

概念证明-这是我的Json,其中包含从sereal字节转换的utf-8字符串

$ hexdump -C min.bin 
00000000  22 3d c3 b3 72 6c 5c 75  30 30 30 33 5c 75 30 30  |"=..rl\u0003\u00|
00000010  30 30 51 6b 6c 61 73 74  5f 75 70 64 61 74 65 20  |00Qklast_update |
00000020  c2 82 c3 9a c3 a6 c3 93  5c 75 30 30 30 35 22     |........\u0005"|
0000002f
decode.pl

use strict;
use warnings;
use JSON;
use Sereal::Decoder;
use Data::Dumper;
use File::Slurp;

my $data = read_file( "min.bin", { binmode => ':raw' } );
my $bin = JSON->new->allow_nonref(1)->decode( $data );
utf8::decode( $bin ); # MAGIC !!!
my $out = Sereal::Decoder->new->decode( $bin );
print(Dumper( $out ));
输出

$VAR1 = {
          'last_update' => 1517923586
        };
(string) (len=30) "=órl\x03\x00Qklast_update \u0082ÚæÓ\x05"
(interface {}) <nil>
(interface {}) <nil>
(*errors.errorString)(0xc42000e370)(bad header: it seems your document was accidentally UTF-8 encoded)
解码

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"

    "github.com/Sereal/Sereal/Go/sereal"
    "github.com/davecgh/go-spew/spew"
)

func main() {
    data, err := ioutil.ReadFile("min.bin")
    if err != nil {
        fmt.Printf("unexpected error while reading fixtures file: '%+v'\n", err)
    }
    var v interface{}
    err = json.Unmarshal(data, &v)
    spew.Dump(v, err)

    var vbody interface{}
    instance := sereal.NewDecoder()
    instance.PerlCompat = false
    str := v.(string)
    // something here to be able to decode?
    err = instance.Unmarshal([]byte(str), vbody)
    spew.Dump(vbody, err)
}
输出

$VAR1 = {
          'last_update' => 1517923586
        };
(string) (len=30) "=órl\x03\x00Qklast_update \u0082ÚæÓ\x05"
(interface {}) <nil>
(interface {}) <nil>
(*errors.errorString)(0xc42000e370)(bad header: it seems your document was accidentally UTF-8 encoded)
问候


Tiago

那不是UTF-8,那是带有文字转义序列的ASCII码。您的文本实际上包含字符串
\u0003
。是@Adrian,但当我转换原始内容(json)时,我发现一个UTF-8字符串,但我需要原始字节。如果我找到0xC3和0xB3,我需要转换为0xF3,引用的输出来自哪里?我只看到三条打印语句,其中一条(错误记录)没有被执行,所以四行输出中只有两行被记录,不清楚是什么。另外,如果您知道
v
将是一个
字符串
,为什么要将
解组到接口{}
,并进行类型转换?您与
utf8::decode
的比较只是让人困惑。该函数相当特定于Perl的Unicode实现。我认为它根本不适用于去,当然也不适用于这种情况。