View Source Nostr.TLV (Nostr Lib v0.1.1)
Provides functions to decode, encode and work with ASN.1 BER-TLV structures. It supports tags encoded on multiple bytes, length encoded on multiple bytes, indefinite length and both primitive and constructed TLVs.
Example:
iex> data = "nprofile1qqsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8gpp4mhxue69uhhytnc9e3k7mgpz4mhxue69uhkg6nzv9ejuumpv34kytnrdaksjlyr9p"
iex> bytes = Nostr.Bech32.nprofile_to_bytes(data)
iex> Nostr.TLV.decode(bytes)
{}
Summary
Types
Represents a BER-TLV structure. The tag
is represented as an integer and header bits are not
separated from the tag. This is to accommodate common usages of the encoding. Primitive TLVs
have a binary value
, while constructed have a list of TLVs. The indefinite_length
field is
set by the decoder to reflect the original byte representation and also serves as instruction to
the encoder on how to encode the length.
Functions
Decodes (recursively) the first binary encoded TLV in the given binary and returns a tuple with
the parsed TLV structure and the remaining data as a binary in the form
{parsed_tlv, remaining_data}
. On error it returns the atom :no_tlv
.
Encodes (recursively) the given TLV structure and returns its binary representation according to the BER-TLV specifications.
Types
Represents a BER-TLV structure. The tag
is represented as an integer and header bits are not
separated from the tag. This is to accommodate common usages of the encoding. Primitive TLVs
have a binary value
, while constructed have a list of TLVs. The indefinite_length
field is
set by the decoder to reflect the original byte representation and also serves as instruction to
the encoder on how to encode the length.
Functions
Decodes (recursively) the first binary encoded TLV in the given binary and returns a tuple with
the parsed TLV structure and the remaining data as a binary in the form
{parsed_tlv, remaining_data}
. On error it returns the atom :no_tlv
.
The decoder tolerates lengths encoded on more bytes than strictly needed, although the ASN.1 specification require encoders to always generate the shortest possible encoding.
Examples
# Primitive TLV + data after its end
iex> Nostr.TLV.decode(<<0x80, 0x02, 0xCA, 0xFE, 0xAA, 0xBB>>)
{%Nostr.TLV{indefinite_length: false, tag: 0x80, value: <<0xCA, 0xFE>>}, <<0xAA, 0xBB>>}
# Constructed TLV
iex> Nostr.TLV.decode(<<0xE0, 0x03, 0x80, 0x01, 0xAA>>)
{%Nostr.TLV{indefinite_length: false, tag: 0xE0, value:
[%Nostr.TLV{indefinite_length: false, tag: 0x80, value: <<0xAA>>}]
}, ""}
# Malformed TLV
iex> Nostr.TLV.decode(<<0x80, 0x02, 0x00>>)
:no_tlv
Encodes (recursively) the given TLV structure and returns its binary representation according to the BER-TLV specifications.
If indefinite_length
is set to true
and the TLV is a constructed one, indefinite length
encoding will be use. For primitive TLVs this field will be ignored, since for primitive TLVs
only definite length is allowed.
The primitive/constructed bit of the tag
field will not be checked for consistency with the
value
field.
Examples
# Primitive TLV
iex> Nostr.TLV.encode(%Nostr.TLV{tag: 0x80, value: <<0xAA, 0xBB>>})
<<0x80, 0x02, 0xAA, 0xBB>>
# Constructed TLV
iex> Nostr.TLV.encode(%Nostr.TLV{tag: 0xE0, value: [%Nostr.TLV{tag: 0x80, value: <<0xAA>>}]})
<<0xE0, 0x03, 0x80, 0x01, 0xAA>>