Package bertlv implements encoding and decoding of BER-TLV structures using struct tags, similar to encoding/json.
go get github.com/skythen/bertlv
Use the bertlv struct tag to map struct fields to BER-TLV tags.
Use the 0x prefix to specify tags as hex bytes. Class and construction are derived from the encoded tag bytes:
type FCI struct {
AID []byte `bertlv:"0x4F"`
Label []byte `bertlv:"0x50"`
Track2 []byte `bertlv:"0x57"`
ExpDate []byte `bertlv:"0x5F24"` // multi-byte tags
Records []Record `bertlv:"0x70"` // constructed tags decode recursively
}Specify tag number and class explicitly:
"<number>,<class>[,options...]"
- number: Decimal tag number (0-16383)
- class: One of
universal,application,context,private
type Data struct {
Field1 []byte `bertlv:"1,universal"`
Field2 []byte `bertlv:"2,application"`
Field3 []byte `bertlv:"3,context"`
}omitempty- skip field during encoding if empty/zerorequired- return error during decoding if tag is not present
type Data struct {
Required []byte `bertlv:"0x4F,required"`
Optional []byte `bertlv:"0x50,omitempty"`
Both []byte `bertlv:"1,universal,required,omitempty"`
}Decode BER-TLV data into a struct:
var result struct {
AID []byte `bertlv:"0x4F"`
Label []byte `bertlv:"0x50"`
}
err := bertlv.Unmarshal(data, &result)opts := bertlv.Options{
DisallowUnknownFields: true,
}
err := bertlv.UnmarshalWithOptions(data, &result, opts)Implement the Unmarshaler interface for custom decoding:
type MyType struct {
Value string
}
func (m *MyType) UnmarshalBERTLV(value []byte) error {
m.Value = string(value)
return nil
}Encode a struct into BER-TLV format:
data := struct {
AID []byte `bertlv:"0x4F"`
Label []byte `bertlv:"0x50"`
}{
AID: []byte{0xA0, 0x00, 0x00, 0x00, 0x04, 0x10, 0x10},
Label: "GoCard",
}
encoded, err := bertlv.Marshal(data)Implement the Marshaler interface for custom encoding:
func (m MyType) MarshalBERTLV() ([]byte, error) {
return []byte(m.Value), nil
}The following Go types can be used as struct fields:
[]byte- raw TLV valuestring- UTF-8 encoded valueint,int8,int16,int32,int64- big-endian signed integersuint,uint8,uint16,uint32,uint64- big-endian unsigned integersbool- single byte (0x00 = false, non-zero = true)struct- nested constructed TLV[]T(slice of structs) - repeated TLV elements