我正在尝试为以下定义执行ASN.1 marshal / unmarshal:
ACEI ::= SEQUENCE {
message MessageFields,
neRegNumber OCTET STRING OPTIONAL,
gpsInfo GpsInfo OPTIONAL,
siteInfo OCTET STRING OPTIONAL,
nlementID INTEGER(0..16777216) OPTIONAL,
...
}
GpsInfo ::= SEQUENCE {
gpsLat INTEGER(-900000000..900000000) OPTIONAL,
gpsLong INTEGER(-1800000000..1800000000) OPTIONAL,
gpsAlt INTEGER OPTIONAL,
...
}
MessageFields ::= SEQUENCE {
messageSequence INTEGER (1..65535),
bsId INTEGER (1..65535) OPTIONAL,
neID INTEGER(0..16777216) OPTIONAL, -- unsigned int
nelementID INTEGER(0..16777216) OPTIONAL, -- unsigned int
...
}
相应的结构是:
type ACEI struct {
Message MessageFields
NeRegNumber []byte `asn1:"optional"`
GPSInfo GPSInfo `asn1:"optional"`
SiteInfo []byte `asn1:"optional"`
NElementID int `asn1:"optional"`
}
type GPSInfo struct {
GpsLatitude int `asn1:"optional"`
GpsLongitude int `asn1:"optional"`
GpsAltitude int `asn1:"optional"`
}
type MessageFields struct {
MessageSequence int
BsId int `asn1:"optional"`
NeID int `asn1:"optional"`
NElementID int `asn1:"optional"`
}
我正在填充结构,编组它们然后将它们转换为十六进制。 当我这样做时,获得的十六进制序列(seqA)是:
302e300f020101020204d2020215b302021a0a040430413042300b02019c020200be020200c80404304330440202309c
当我在http://asn1-playground.oss.com/上执行相同操作时,我得到以下十六进制序列(seqB):
302AA00F 80010181 0204D282 0215B383 021A0A81 020A0BA2 0B80019C 810200BE 820200C8 83020C0D 8402309C
我将这些十六进制序列输入到unmarshal函数中;当seqA被正确解组时,解组seqB会给我以下错误:
解组时出错:asn1:结构错误:标签不匹配(16 vs {class:2 tag:0 length:15 isCompound:true}){optional:false explicit:false application:false defaultValue:tag :stringType:0 timeType:0 set:false omitEmpty:false} MessageFields @ 2
这是编组/解组的代码:
func main() {
//Marshalling
messageSequence := structs.MessageFields{1, 1234, 5555, 6666}
gpsInfo := structs.GPSInfo{-100, 190, 200}
val := structs.ACEI{messageSequence, []byte("0A0B"), gpsInfo, []byte("0C0D"), 12444}
hexmdata := asn1Marshal(val)
//Unmarshalling hex sequence (seqA) generated by go code
res1, _ := asn1Unmarshal(hexmdata)
fmt.Println(res1)
//Unmarshalling hex sequence (seqB) generated by http://asn1-playground.oss.com/
res2, _ := asn1Unmarshal(strings.ToLower("302AA00F800101810204D2820215B383021A0A81020A0BA20B80019C810200BE820200C883020C0D8402309C"))
fmt.Println(res2)
}
func asn1Unmarshal(hexmdata string) (structs.ACEI, error){
fmt.Println(hexmdata)
s, _ := hex.DecodeString(hexmdata)
res := structs.ACEI{}
_, err := asn1.Unmarshal(s, &res)
if err != nil {
fmt.Println("Error while unmarshalling: ", err)
}
return res, err
}
func asn1Marshal(data structs.ACEI) string {
mdata, _ := asn1.Marshal(data)
hexmdata := hex.EncodeToString(mdata)
return hexmdata
}
编辑:相反,转到http://asn1-playground.oss.com/的转码序列(seqA)给出了这个错误:
ACEI SEQUENCE: tag = [UNIVERSAL 16] constructed; length = 46
D0033E: Tag mismatch or tag not expected: [UNIVERSAL 16] (expected tag [0]); check field 'message' (type: MessageFields) of PDU #1 'ACEI'.
*SKIPPED*: tag = [UNIVERSAL 16] constructed; length = 15
<skipped>
D0033E: Tag mismatch or tag not expected: [UNIVERSAL 4] (expected tag [0]); check field 'message' (type: MessageFields) of PDU #1 'ACEI'.
*SKIPPED*: tag = [UNIVERSAL 4] primitive; length = 4
<skipped>
D0033E: Tag mismatch or tag not expected: [UNIVERSAL 16] (expected tag [0]); check field 'message' (type: MessageFields) of PDU #1 'ACEI'.
*SKIPPED*: tag = [UNIVERSAL 16] constructed; length = 11
<skipped>
D0033E: Tag mismatch or tag not expected: [UNIVERSAL 4] (expected tag [0]); check field 'message' (type: MessageFields) of PDU #1 'ACEI'.
*SKIPPED*: tag = [UNIVERSAL 4] primitive; length = 4
<skipped>
D0033E: Tag mismatch or tag not expected: [UNIVERSAL 2] (expected tag [0]); check field 'message' (type: MessageFields) of PDU #1 'ACEI'.
*SKIPPED*: tag = [UNIVERSAL 2] primitive; length = 2
<skipped>
D0049E: Field omitted: "message"; check PDU #1 'ACEI'.
S0012E: Decoding of PDU #1 failed with the return code '5'.
编辑2:根据@ YaFred的建议编辑结构后,我的结构现在看起来像这样:
type ACEI struct {
Message MessageFields `asn1:"application,tag:0,implicit"`
NeRegNumber []byte `asn1:"application,tag:1,implicit,optional"`
GPSInfo GPSInfo `asn1:"application,tag:2,implicit,optional"`
SiteInfo []byte `asn1:"application,tag:3,implicit,optional"`
NElementID int `asn1:"application,tag:4,implicit,optional"`
}
type GPSInfo struct {
GpsLatitude int `asn1:"application,tag:0,implicit,optional"`
GpsLongitude int `asn1:"application,tag:1,implicit,optional"`
GpsAltitude int `asn1:"application,tag:2,implicit,optional"`
}
type MessageFields struct {
MessageSequence int `asn1:"application,tag:0,implicit"`
BsId int `asn1:"application,tag:1,implicit,optional"`
NeID int `asn1:"application,tag:2,implicit,optional"`
NElementID int `asn1:"application,tag:3,implicit,optional"`
}
使用这些结构的编组为我提供了与asn playground相同的十六进制代码。但是,解组失败并出现以下错误:
十六进制代码: 302aa00f800101810204d2820215b383021a0a81020a0ba20b80019c810200be820200c883020c0d8402309c
错误(我之前尝试使用go代码解组十六进制代码(来自asn playground)时遇到的错误):
解组时出错:asn1:结构错误:标签不匹配(0 vs {class:2 tag:0 length:15 isCompound:true}){optional:false explicit:false application:true defaultValue:tag:0xc042008348 stringType:0 timeType:0 set:false omitEmpty:false} MessageFields @ 2
编辑3:删除&#34;应用程序&#34;结构中的标记可以帮助我按预期解组十六进制代码。
答案 0 :(得分:1)
您输入类型的位置(使用工具以及http://asn1-playground.oss.com/),必须使用模块。如果没有,它不是一个有效的asn1规范(你的工具和oss.com应该拒绝它。)
My-module DEFINITIONS ::=
BEGIN
ACEI ::= SEQUENCE {
etc ...
END
工具在不知道模块标记上下文的情况下接受编码类型的事实是https://stackoverflow.com/questions/tagged/asn.1上许多问题的原因
要回答第二个问题(关于长度的不同),你应该显示你给oss.com的价值......很可能:
neRegNumber '0A0B'H
siteInfo '0C0D'H
它们都是2个字节长
但是当你写[]byte("0A0B")
时,你肯定会要求Go给你字符串“0A0B”的字节(确实是ASCII格式的30 41 30 42)
我认为[]byte{10,11}
应该为您提供'0A0B'H
EDITED
如果您的工具没有使用asn.1模块,您仍然可以自己进行自动标记
ACEI ::= SEQUENCE {
message [0] IMPLICIT MessageFields,
neRegNumber [1] IMPLICIT OCTET STRING OPTIONAL,
gpsInfo [2] IMPLICIT GpsInfo OPTIONAL,
siteInfo [3] IMPLICIT OCTET STRING OPTIONAL,
nlementID [4] IMPLICIT INTEGER(0..16777216) OPTIONAL,
...
}
GpsInfo ::= SEQUENCE {
gpsLat [0] IMPLICIT INTEGER(-900000000..900000000) OPTIONAL,
gpsLong [1] IMPLICIT INTEGER(-1800000000..1800000000) OPTIONAL,
gpsAlt [2] IMPLICIT INTEGER OPTIONAL,
...
}
MessageFields ::= SEQUENCE {
messageSequence [0] IMPLICIT INTEGER (1..65535),
bsId [1] IMPLICIT INTEGER (1..65535) OPTIONAL,
neID [2] IMPLICIT INTEGER(0..16777216) OPTIONAL, -- unsigned int
nelementID [3] IMPLICIT INTEGER(0..16777216) OPTIONAL, -- unsigned int
...
}
EDITED 2(基于与@Aarvi的聊天)
我刚想到https://golang.org/pkg/encoding/asn1/不涉及ASN.1编译器。
而是手动编写和注释Go结构。
因此遵循ASN.1类型(在选择了AUTOMATICS TAGS的模块中)
GpsInfo ::= SEQUENCE {
gpsLat INTEGER(-900000000..900000000) OPTIONAL,
gpsLong INTEGER(-1800000000..1800000000) OPTIONAL,
gpsAlt INTEGER OPTIONAL,
...
}
必须像这样手动编写
type GPSInfo struct {
GpsLatitude int `asn1:"tag:0,implicit,optional"`
GpsLongitude int `asn1:"tag:1,implicit,optional"`
GpsAltitude int `asn1:"tag:2,implicit,optional"`
}