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'