在Go?
中,这个Perl程序的等价物是什么?use utf8;
my $bin = "..."; # the data may came from file, network, etc
utf8::decode( $bin ); # Encode::decode( 'UTF-8', $bin ) also works
在http://perldoc.perl.org/utf8.html
中定义我尝试了几种形式的转换/规范化/转换为bytes / runes / etc而没有成功。
上下文:
我使用Sereal(https://github.com/Sereal/Sereal)来序列化NoSQL数据库中的一些数据结构,首先我们有一个Perl 5.12.2版本,我们正在使用Go。 Sereal格式是二进制文件
然而,不知何故,一些perl程序在最终的BLOB(UTF-8字符串)中进行了额外的JSON编码/解码,因此对于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
};
decode.go
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)
}
输出
(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)
编辑:此代码有效,但我认为这不是正确的方法:
buff := &bytes.Buffer{}
for len(s) > 0 {
r, size := utf8.DecodeRuneInString( s )
buff.WriteByte( byte(r ) )
s = s[size:]
}
rawBytes := buff.Bytes() // yeah
此致
蒂亚戈