使用 asn.1 的结构数组

array of struct using asn.1

正在学习编写 asn.1 语法。我希望 asn.1 提供编写序列数组的功能。它有一个相同类型的结构模式,一次又一次地重复,但有微小的修改。我想知道 ASN.1 是否允许我编写数组类型的语法来适应它而不是编写这么大的语法。

gamePlayer {
gamePlayer {
    gamePlayer type: user (0)
    playerDetail  {
        name: player_1
        team: red
        ip: 10.3.3.1
        membership: level_2
    }
}
gamePlayer {
    gamePlayer type: user (0)
    playerDetail  {
        name: player_2
        team: blue
        ip: 10.3.3.2
        membership: level_4
    }
}
gamePlayer {
    gamePlayer type: ai (1)
    playerDetail  {
        name: ai_1
        team: red
        bot: bikeBot
    }
}
gamePlayer {
    gamePlayer type: ai (1)
    playerDetail  {
        name: ai_2
        team: blue
        bot: bikeBot
    }
}
gamePlayer {
    gamePlayer type: ai (1)
    playerDetail  {
        name: ai_3
        team: blue
        bot: carBot
    }
}

}

我会使用 ENUMERATED 作为玩家类型。 OPTIONAL 成员可以解决 playerDetail 中的差异。游戏玩家数组将由 SEQUENCE OF.

解决

这是ASN.1模块的例子(我没测试过是否正确) GamePlayerModule

DEFINITIONS IMPLICIT TAGS ::= BEGIN

GamePlayers ::= SEQUENCE OF GamePlayer

Gameplayer ::= SEQUENCE {
   type ::=         ENUMERATED
                       {
                          user  (0)
                          ai    (1)

                       },
   playerDetail     PlayerDetail
}

PlayerDetail ::= SEQUENCE {
    name            UTF8STRING,
    team            UTF8STRING,
    ip          [0] UTF8STRING OPTIONAL,
    membership  [1] UTF8STRING OPTIONAL,
    bot         [2] UTF8STRING OPTIONAL
}

END

在 ASN.1 中有很多方法可以给这只猫蒙皮。一种方式:

Player ::= SEQUENCE {
    name    UTF8String,
    team    UTF8String,

    humanOrAI CHOICE {
       human [0] HumanInfo,
       ai    [1] AIInfo
    }
}

HumanInfo ::= SEQUENCE {
    ip         OCTET STRING (SIZE (4))
    membership UTF8String
}

AIInfo ::= ENUMERATED { bikeBot, carBot }

CHOICE 的使用可能是允许您将这些项目混合在一起的合适方式。 (你可能会考虑如果让人类接管一个AI玩家会发生什么。)

在大多数协议中,通常将 IP 地址指定为 OCTET STRINGs,但这只是一个实现细节。

有一组很好的在线资源可用于学习 ASN.1:请参阅 this tutorial for something quick; Larmouth's and Dubuisson's 在线书籍。 Larmouth 更容易接近,但 Dubuisson 可能更彻底。