Parser and serializer for Bencode, the encoding used by BitTorrent for storing and transmitting loosely structured data.
Bencoding uses ASCII characters as delimiters and digits. While less efficient than a binary format, this makes debugging easier and means it is unaffected by endianness. Like JSON or tagged-netstrings, it does not require a schema to parse. Unlike JSON, it's easy to embed binary data in the messages (as with netstrings). Bencoding also avoids some of the memory buffering problems of tagged-netstrings by placing type information at the start of the data, not the end, and by not requiring a length prefix for nested/complex data types, only for byte strings.
A Bencoding is canonical for the data provided, each complex value only has one possible encoding (since dictionary keys must be lexicographically sorted as part of the spec). This means you can compare equality of messages, or parts of messages, without having to unpack them. It's also relatively easy to encode or decode bencoded values manually without complicated escape sequences, making it a potential candidate for embedded and low powered devices.
Bencoding supports four different types of values, which are mapped to scheme types as follows:
|dictionaries||a-lists in the form (symbol . *)|
API[procedure] (read-bencode #!optional port)
Reads Bencoded data from port, defaults to current-input-port.[procedure] (write-bencode data #!optional port)
Writes Bencoded data to port, defaults to current-output-port.[procedure] (bencode->string data)
Returns Bencoded string for provided data.[procedure] (string->bencode str)
Returns Bencode data parsed from provided string.
(use bencode) (string->bencode "l5:helloi42ee") ;; => #("hello" 42) (bencode->string '((name . "CHICKEN"))) ;; => "d4:name7:CHICKENe"