Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Encoder

Constructor

Encoder(encoding: Encoding)

Creates a new in-memory encoder. Elements are appended in call order. Call finish() to retrieve the accumulated bytes.

Primitive encode methods — raw values

MethodSignatureASN.1 type
encode_integer(value: int)INTEGER — accepts any Python int (arbitrary magnitude via bigint path)
encode_octet_string(data: bytes)OCTET STRING
encode_oid(value: ObjectIdentifier)OBJECT IDENTIFIER
encode_bit_string(value: BitString)BIT STRING
encode_boolean(value: bool)BOOLEAN
encode_utc_time(value: UtcTime)UTCTime
encode_generalized_time(value: GeneralizedTime)GeneralizedTime
encode_real(value: float)REAL
encode_null()NULL
encode_utf8_string(value: str)UTF8String
encode_printable_string(value: str)PrintableString — raises ValueError for invalid chars
encode_ia5_string(value: str)IA5String — raises ValueError for non-ASCII
encode_numeric_string(value: str)NumericString — raises ValueError for non-digit/non-space
encode_teletex_string(data: bytes)TeletexString / T61String
encode_visible_string(value: str)VisibleString — raises ValueError for invalid chars
encode_general_string(data: bytes)GeneralString
encode_universal_string(value: str)UniversalString (UCS-4 BE)
encode_bmp_string(value: str)BMPString (UCS-2 BE) — raises ValueError for non-BMP code points

Primitive encode methods — typed objects

Each primitive type has an _object variant that accepts the corresponding Python wrapper instead of a raw value.

MethodAccepts
encode_integer_objectInteger
encode_octet_string_objectOctetString
encode_oid_objectObjectIdentifier (alias for encode_oid)
encode_bit_string_objectBitString (alias for encode_bit_string)
encode_boolean_objectBoolean
encode_utc_time_objectUtcTime (alias for encode_utc_time)
encode_generalized_time_objectGeneralizedTime (alias for encode_generalized_time)
encode_real_objectReal
encode_null_objectNull
encode_utf8_string_objectUtf8String
encode_printable_string_objectPrintableString
encode_ia5_string_objectIA5String
encode_numeric_string_objectNumericString
encode_teletex_string_objectTeletexString
encode_visible_string_objectVisibleString
encode_general_string_objectGeneralString
encode_universal_string_objectUniversalString
encode_bmp_string_objectBmpString

Container / tagging encode methods

MethodSignatureDescription
encode_sequence(inner_bytes: bytes)Wrap inner_bytes with SEQUENCE TLV (tag 0x30).
encode_set(inner_bytes: bytes)Wrap inner_bytes with SET TLV (tag 0x31).
encode_explicit_tag(tag_num: int, tag_class: str, inner_bytes: bytes)Wrap inner_bytes in an explicit constructed tag. tag_class: "Context", "Application", "Private".
encode_implicit_tag(tag_num: int, tag_class: str, is_constructed: bool, value_bytes: bytes)Emit an implicit tag over raw value bytes. Set is_constructed=True for SEQUENCE/SET underlying types.

Finalisation

MethodReturnsDescription
finish()bytesConsume the encoder and return the accumulated DER/BER bytes. The encoder is reset and can be reused (rarely needed).

Full class stub

class Encoder:
    def __init__(self, encoding: Encoding) -> None: ...

    # Primitive types
    def encode_integer(self, value: int) -> None: ...
    # Accepts any Python int, including values beyond i64/i128 range (e.g.
    # 20-byte X.509 serial numbers up to 160 bits).
    def encode_integer_object(self, value: Integer) -> None: ...
    def encode_octet_string(self, data: bytes) -> None: ...
    def encode_octet_string_object(self, value: OctetString) -> None: ...
    def encode_oid(self, value: ObjectIdentifier) -> None: ...
    def encode_bit_string(self, value: BitString) -> None: ...
    def encode_boolean(self, value: bool) -> None: ...
    def encode_real(self, value: float) -> None: ...
    def encode_real_object(self, value: Real) -> None: ...
    def encode_null(self) -> None: ...
    def encode_null_object(self, value: Null) -> None: ...
    def encode_utc_time(self, value: UtcTime) -> None: ...
    def encode_generalized_time(self, value: GeneralizedTime) -> None: ...

    # String types
    def encode_utf8_string(self, value: str) -> None: ...
    def encode_utf8_string_object(self, value: Utf8String) -> None: ...
    def encode_printable_string(self, value: str) -> None: ...       # Raises ValueError for invalid chars
    def encode_printable_string_object(self, value: PrintableString) -> None: ...
    def encode_ia5_string(self, value: str) -> None: ...             # Raises ValueError for non-ASCII
    def encode_ia5_string_object(self, value: IA5String) -> None: ...
    def encode_numeric_string(self, value: str) -> None: ...         # Raises ValueError for non-digit/space
    def encode_numeric_string_object(self, value: NumericString) -> None: ...
    def encode_teletex_string(self, data: bytes) -> None: ...        # Raw bytes, tag 20
    def encode_teletex_string_object(self, value: TeletexString) -> None: ...
    def encode_visible_string(self, value: str) -> None: ...         # Raises ValueError for control chars
    def encode_visible_string_object(self, value: VisibleString) -> None: ...
    def encode_general_string(self, data: bytes) -> None: ...        # Raw bytes, tag 27
    def encode_general_string_object(self, value: GeneralString) -> None: ...
    def encode_universal_string(self, value: str) -> None: ...       # UCS-4 BE, tag 28
    def encode_universal_string_object(self, value: UniversalString) -> None: ...
    def encode_bmp_string(self, value: str) -> None: ...             # UCS-2 BE, tag 30; Raises ValueError if > U+FFFF
    def encode_bmp_string_object(self, value: BmpString) -> None: ...

    # Constructed / tagged
    def encode_sequence(self, inner_bytes: bytes) -> None: ...
    # Wraps pre-encoded bytes in a SEQUENCE TLV (tag 0x30).
    # Encode inner elements into a separate Encoder, call finish(), then pass
    # the result here.

    def encode_set(self, inner_bytes: bytes) -> None: ...
    # Wraps pre-encoded bytes in a SET TLV (tag 0x31).

    def encode_explicit_tag(self, tag_num: int, tag_class: str, inner_bytes: bytes) -> None: ...
    # Wraps pre-encoded bytes in an explicit tag TLV (always constructed).
    # tag_class must be "Context", "Application", or "Private".
    # Raises ValueError for any other value.

    def encode_implicit_tag(self, tag_num: int, tag_class: str,
                            is_constructed: bool, value_bytes: bytes) -> None: ...
    # Writes an implicit tag with the given value bytes (not a full TLV).
    # For implicit tagging the original type tag is replaced, so pass the raw
    # value content (not the original TLV).  Set is_constructed=True when the
    # underlying type is SEQUENCE, SET, or another constructed form.
    # tag_class must be "Context", "Application", or "Private".
    #
    # Example — [1] IMPLICIT INTEGER with raw value bytes b'\x2a':
    #   enc.encode_implicit_tag(1, "Context", False, b'\x2a')

    def finish(self) -> bytes: ...

Usage examples

Encoding ASN.1 data

import synta

# Encode an INTEGER
encoder = synta.Encoder(synta.Encoding.DER)
encoder.encode_integer(42)
output = encoder.finish()
print(output.hex())  # Output: 02012a

# Encode an OCTET STRING
encoder = synta.Encoder(synta.Encoding.DER)
encoder.encode_octet_string(b'hello')
output = encoder.finish()
print(output.hex())  # Output: 040568656c6c6f

# Encode a NULL
encoder = synta.Encoder(synta.Encoding.DER)
encoder.encode_null()
output = encoder.finish()
print(output.hex())  # Output: 0500

# Encode a REAL
import math
encoder = synta.Encoder(synta.Encoding.DER)
encoder.encode_real(0.0)
output = encoder.finish()
print(output.hex())  # Output: 0900

encoder = synta.Encoder(synta.Encoding.DER)
encoder.encode_real(math.inf)
output = encoder.finish()
print(output.hex())  # Output: 090140

# Encode a UTF8String
encoder = synta.Encoder(synta.Encoding.DER)
encoder.encode_utf8_string("Hello, world!")
output = encoder.finish()

# Encode a GeneralString (Kerberos realm, FreeIPA use-case)
encoder = synta.Encoder(synta.Encoding.DER)
encoder.encode_general_string(b"EXAMPLE.COM")
output = encoder.finish()

# Encode a BMPString (Microsoft AD-CS template name)
encoder = synta.Encoder(synta.Encoding.DER)
encoder.encode_bmp_string("User")
output = encoder.finish()

Building SEQUENCE structures

Encode inner elements into a separate Encoder, then wrap the output in a SEQUENCE or SET using the outer Encoder. Use encode_explicit_tag to add explicit context tags.

import synta

# Build SEQUENCE { INTEGER 42, BOOLEAN TRUE }
inner = synta.Encoder(synta.Encoding.DER)
inner.encode_integer(42)
inner.encode_boolean(True)

outer = synta.Encoder(synta.Encoding.DER)
outer.encode_sequence(inner.finish())
result = outer.finish()
# result == b'\x30\x06\x02\x01\x2a\x01\x01\xff'

# Build [1] EXPLICIT INTEGER 99 (explicit context tag)
inner = synta.Encoder(synta.Encoding.DER)
inner.encode_integer(99)

outer = synta.Encoder(synta.Encoding.DER)
outer.encode_explicit_tag(1, "Context", inner.finish())
result = outer.finish()
# First byte 0xa1 = context-specific constructed tag [1]