Python support
The nShield Python module nfddds
can be used to encode and decode between the DDDS wire format and a Python representation of the DDDS objects.
nfddds.encode
accepts any Python object which can be interpreted as a DDDS object:
Python class | DDDS equivalent |
---|---|
int |
integer |
str |
string |
nfddds.Symbol |
symbol |
bytes bytearray nfkm.ByteBlock |
byte-block |
bool |
symbols 'True' and 'False' |
tuple list |
list |
dict |
map |
set |
set |
nfddds.decode
accepts input which can be interpreted as a list of octets, i.e. a byte string, byte array, list of integers or nfkm.ByteBlock.
Below are a few examples using the nfddds
module.
A longer use case can be seen in the nShield Warrants appnote where nfddds
is used to decode and view an HSM warrant.
Example 1 - decoding a string and symbol
As per the wire format specification, the first octet 0x25
indicates a DDDS string where the following 5 octets are the UTF-8 encoding of the string.
If the first octet is replaced by 0x35
, this will be a DDDS symbol made up of 5 octets.
>>> nfddds.decode([0x25, 0x68, 0x65, 0x6c, 0x6c, 0x6f])
'hello'
>>> type(nfddds.decode([0x25, 0x68, 0x65, 0x6c, 0x6c, 0x6f]))
<class 'nfddds.String'>
>>> nfddds.decode([0x35, 0x68, 0x65, 0x6c, 0x6c, 0x6f])
'hello'
>>> type(nfddds.decode([0x35, 0x68, 0x65, 0x6c, 0x6c, 0x6f]))
<class 'nfddds.Symbol'>
Example 2 - decoding a map
The first octet 0xb3
indicates a DDDS map with three key-value pairs.
In this example, the keys are one-octet DDDS integers and the values are two-octect DDDS strings.
>>> nfddds.decode([0xb3, 0x00, 0x21, 0x61, 0x01, 0x21, 0x62, 0x02, 0x21, 0x63])
{0: 'a', 1: 'b', 2: 'c'}
Example 3 - encoding a set and list
If a Python set and list contain the same elements and list(setname) == listname
, they will encode to the same wire format, except the first four bits will be 1001
(or hex 9
) for lists and 1010
(or hex a
) for sets.
>>> nfddds.encode({1, 2, 3, 4})
b'\xa4\x01\x02\x03\x04'
>>> nfddds.encode([1, 2, 3, 4])
b'\x94\x01\x02\x03\x04'