Maison > développement back-end > Golang > Comment puis-je analyser les messages Protobuf inconnus sans informations de type ?

Comment puis-je analyser les messages Protobuf inconnus sans informations de type ?

Patricia Arquette
Libérer: 2024-11-28 01:36:10
original
641 Les gens l'ont consulté

How Can I Parse Unknown Protobuf Messages Without Type Information?

Démarshalling de messages proto inconnus sans informations de type

Bien que la méthode proto.Unmarshal() de protobuf nécessite un type de message connu, les messages inconnus présentent un défi . Cependant, nous pouvons extraire des informations limitées à l'aide du package protowire.

Approche :

  1. Utilisez protowire.ConsumeField() pour parcourir la charge utile du message inconnu.
  2. Identifier le type de champ, qui pourrait être :

    • Varint
    • Fixed64
    • Bytes
    • StartGroup
    • Fixed32
  3. Analyser la charge utile du champ en fonction de son tapez.
  4. Gérez les sous-messages en analysant de manière récursive leurs charges utiles.

Modèle de données :

type Field struct {
    Tag Tag
    Val Val
}

type Tag struct {
    Num int32
    Type protowire.Type
}

type Val struct {
    Payload interface{}
    Length int
}
Copier après la connexion

Parseur :

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
}
Copier après la connexion

Exemple (Structure du message) :

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

message Bar {
  string c = 1;
}
Copier après la connexion

Exemple (sortie analysée) :

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}}
Copier après la connexion

Considérations :

  • Sous-messages : Analyse récursive de charges utiles d'octets identifiées comme messages.
  • Champs répétés : Gérés en fonction de numéros de balise de champ identiques.
  • Cartes : Supposées être similaires aux k répétés /v paires.
  • Oneofs : Les informations sur le type d'union sont perdues, seule la valeur réelle la valeur est analysée.

Bien que ce code ne fournisse pas une solution complète de niveau production, il offre une méthode pour analyser les charges utiles de proto inconnues tout en préservant certaines informations sémantiques.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal