Bencoding is a way to encode integers, strings, lists, and hash-tables
as strings (serialization), and bdecoding does the reverse operation.
It is part of the torrent metafile specification at
http://bittorrent.org/beps/bep_0003.html
Notice that torrent files are binary files, since they contain
strings with octets instead of characters.
Data encoded and decoded
------------------------
+----------------------+----------------------+----------------------+
| Lisp type | BEncoded type | Lisp type |
+----------------------+----------------------+----------------------+
| integer | integer (i) | integer |
+----------------------+----------------------+----------------------+
| octets | string (:) | string or octets¹ |
+----------------------+----------------------+----------------------+
| string | string (:) | string or octets¹ |
+----------------------+----------------------+----------------------+
| symbol | string (:) | string² |
+----------------------+----------------------+----------------------+
| character | string (:) | string |
+----------------------+----------------------+----------------------+
| hash-table³ | dict (d) | hash-table |
+----------------------+----------------------+----------------------+
| list | list (l) | list |
+----------------------+----------------------+----------------------+
¹: OCTETS are a vector of (unsigned-byte 8), if a string contains only
the standard characters, then it's read as a string, otherwise as an
OCTETS.
²: in a dict, key strings can be converted into symbols.
³: all keys must be string designators.
Key map
-------
Encoded dictionaries use strings as key. Sometimes, the string
contains spaces, sometimes it contains dashes. It could contain any
characters.
By default, we map keywords to strings by merely downcasing them (and
vice-versa, by interning the upcased string in the KEYWORD package).
To map keywords to a different string, we use key-map-exceptions.
Since dictionaries may contain other dictionaries as values, an entry
in the key-map-exceptions may specify another key-map-exceptions to be
used when reading the value of the dictionary entry.
A key-map-exceptions is an a-list mapping keywords to either:
- a string, or
- a p-list containing the keys :string and/or :key-map.
The string substitutes the keyword in the serialized dictionary; the
key-map is another key-map exceptions a-list to be used when reading
the value of that dictionary entry.
*TORRENT-KEY-MAP-EXCEPTIONS* is the key-map-exceptions that can be
used to read and write torrent files, binding it to *KEY-MAP-EXCEPTIONS*.
Decoding BEncoded strings or streams
------------------------------------
::
(with-open-stream (torrent "example.torrent" :element-type '(unsigned-byte 8))
;; torrent files contain binary 'strings'...
(let ((*key-map-exceptions* *torrent-key-map-exceptions*))
(bdecode-from-binary-stream torrent)))
(with-open-stream (stream "file.bencoded")
(bdecode-from-character-stream torrent))
(bdecode-from-string "li43e4:spaml4:spam4:eggsed3:cow3:moo4:spam4:eggsed4:spaml1:a1:beee")
Encoding BEncoded strings or streams
------------------------------------
::
(with-open-stream (torrent "example.torrent"
:element-type '(unsigned-byte 8)
:direction :output
:if-does-not-exist :create
:if-exists :supersede)
;; torrent files contain binary 'strings'...
(let ((*key-map-exceptions* *torrent-key-map-exceptions*))
(bencode-to-binary-stream object torrent)))
(with-open-stream (stream "file.bencoded"
:direction :output
:if-does-not-exist :create
:if-exists :supersede)
(bencode-to-character-stream object stream))
(bencode-to-string (list 42 '("aa" bb #\c :dd)
(hashtable :elements '((one 1) ("two" "2") (:three-and-one-third (x x x))))
(hashtable :elements '((:one 1) (:two "2") (:three-and-one-third (x x x))))))
--> "li42el2:aa2:BB1:c2:DDed3:onei1e19:three-and-one-thirdl1:X1:X1:Xe3:two1:2ed3:onei1e19:three-and-one-thirdl1:X1:X1:Xe3:two1:2ee"
License:
AGPL3
Copyright Pascal J. Bourguignon 2010 - 2012
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program.
If not, see <http://www.gnu.org/licenses/>
|
*key-map-exceptions* |
variable |
Current key-map exceptions. A key-map-exceptions is an a-list mapping keywords to either: - a string, or - a p-list containing the keys :string and/or :key-map. The string substitutes the keyword in the serialized dictionary; the key-map is another key-map exceptions a-list to be used when reading the value of that dictionary entry.
Initial value: NIL
|
*torrent-key-map-exceptions* |
variable |
Key-map exceptions for torrent files.
Initial value: ((CREATED-BY . created by) (CREATION-DATE . creation date) (INFO STRING info KEY-MAP ((PIECE-LENGTH . piece length))))
|
(bdecode-from-binary-stream input) |
function |
Reads a BEncoded object from the INPUT binary stream.
|
(bdecode-from-character-stream input) |
function |
Reads a BEncoded object from the INPUT character stream.
|
(bdecode-from-string bencoded-string) |
function |
Returns the object BEncoded in the BENCODED-STRING.
|
(bencode-to-binary-stream object output) |
function |
Writes a BEncoded OBJECT to the OUTPUT binary stream.
|
(bencode-to-character-stream object output) |
function |
Writes a BEncoded OBJECT to the OUTPUT character stream.
|
(bencode-to-string object) |
function |
Returns a string containing the BEncoded OBJECT.