Rumah > pembangunan bahagian belakang > Golang > Bagaimanakah Saya Boleh Menghuraikan Mesej Protobuf Tidak Diketahui Tanpa Maklumat Jenis?

Bagaimanakah Saya Boleh Menghuraikan Mesej Protobuf Tidak Diketahui Tanpa Maklumat Jenis?

Patricia Arquette
Lepaskan: 2024-11-28 01:36:10
asal
682 orang telah melayarinya

How Can I Parse Unknown Protobuf Messages Without Type Information?

Unknown Message Proto Demarshalling Without Type Information

Walaupun kaedah proto.Unmarshal() protobuf memerlukan jenis mesej yang diketahui, mesej yang tidak diketahui memberikan cabaran . Walau bagaimanapun, kami boleh mengekstrak maklumat terhad menggunakan pakej protowire.

Pendekatan:

  1. Gunakan protowire.ConsumeField() untuk beralih melalui muatan mesej yang tidak diketahui.
  2. Kenal pasti jenis medan, yang boleh menjadi:

    • Varin
    • Fixed64
    • Bytes
    • StartGroup
    • Fixed32
  3. Menghuraikan muatan medan berdasarkannya taip.
  4. Kendalikan submesej dengan menghuraikan muatannya secara rekursif.

Model Data:

type Field struct {
    Tag Tag
    Val Val
}

type Tag struct {
    Num int32
    Type protowire.Type
}

type Val struct {
    Payload interface{}
    Length int
}
Salin selepas log masuk

Penghurai:

func parseUnknown(b []byte) []Field {
    // Iteratively consume and parse fields
    for len(b) > 0 {
        // Read field tag and length
        n, t, fieldlen := protowire.ConsumeField(b)
        if fieldlen < 1 {
            return nil
        }
        field := Field{Tag: Tag{Num: int32(n), Type: t}}

        // Read and process tag and value content
        _, _, taglen := protowire.ConsumeTag(b[:fieldlen])
        if taglen < 1 {
            return nil
        }
        var v interface{}
        var vlen int
        switch t {
            case protowire.VarintType:
                v, vlen = protowire.ConsumeVarint(b[taglen:fieldlen])
            case protowire.Fixed64Type:
                v, vlen = protowire.ConsumeFixed64(b[taglen:fieldlen])
            case protowire.BytesType:
                v, vlen = protowire.ConsumeBytes(b[taglen:fieldlen])
                sub := parseUnknown(v.([]byte))
                if sub != nil {
                    v = sub
                }
            case protowire.StartGroupType:
                v, vlen = protowire.ConsumeGroup(n, b[taglen:fieldlen])
                sub := parseUnknown(v.([]byte))
                if sub != nil {
                    v = sub
                }
            case protowire.Fixed32Type:
                v, vlen = protowire.ConsumeFixed32(b[taglen:fieldlen])
        }
        if vlen < 1 {
            return nil
        }

        field.Val = Val{Payload: v, Length: vlen - taglen}
        fields = append(fields, field)
        b = b[fieldlen:]
    }
    return fields
}
Salin selepas log masuk

Contoh (Struktur Mesej):

message Foo {
  string a = 1;
  string b = 2;
  Bar bar = 3;
}

message Bar {
  string c = 1;
}
Salin selepas log masuk

Contoh (Output Dihurai):

main.Field{Tag:main.Tag{Num:1, Type:2}, Val:main.Val{Payload:[]uint8{0x41}, Length:1}}
main.Field{Tag:main.Tag{Num:2, Type:2}, Val:main.Val{Payload:[]uint8{0x42}, Length:1}}
main.Field{Tag:main.Tag{Num:1, Type:2}, Val:main.Val{Payload:[]uint8{0x43}, Length:1}}
main.Field{Tag:main.Tag{Num:3, Type:2}, Val:main.Val{Payload:[]main.Field{main.Field{Tag:main.Tag{Num:1, Type:2}, Val:main.Val{Payload:[]uint8{0x43}, Length:1}}}, Length:3}}
Salin selepas log masuk

Pertimbangan:

  • Sub-mesej: Penghuraian rekursif daripada muatan bait yang dikenal pasti sebagai mesej.
  • Medan berulang: Dikendalikan berdasarkan nombor teg medan yang sama.
  • Peta: Diandaikan serupa dengan berulang pasangan k/v.
  • Salah satu: Kesatuan maklumat jenis hilang, hanya nilai sebenar dihuraikan.
Walaupun kod ini tidak menyediakan penyelesaian gred pengeluaran yang lengkap, ia menawarkan kaedah untuk menghuraikan muatan proto yang tidak diketahui sambil mengekalkan beberapa maklumat semantik.

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Menghuraikan Mesej Protobuf Tidak Diketahui Tanpa Maklumat Jenis?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan