How Bencode Encoding Works in Torrent Files

Bencode (pronounced "B-encode") is the lightweight serialization and data encoding format created specifically for the BitTorrent protocol. It provides a simple, platform-independent mechanism to store structured metadata inside .torrent files and facilitate communication between BitTorrent clients and trackers. This article explains the four fundamental data types used in Bencode, details how they assemble the internal architecture of a torrent file, and highlights why this specific encoding format is critical for generating unique torrent identifiers.


The Four Bencode Data Types

Bencode supports four basic data types: integers, byte strings, lists, and dictionaries. Each data type uses ASCII delimiter characters to mark its boundaries, making parsing fast and unambiguous.

1. Integers

Integers are encoded with a leading i, followed by the number in base-10 ASCII representation, and terminated with an e.

  • Format: i<integer>e
  • Examples:
    • 42 becomes i42e
    • -15 becomes i-15e
    • 0 becomes i0e
  • Rules: Leading zeros are not allowed (e.g., i03e is invalid), though i0e is valid. Negative zero (i-0e) is prohibited.

2. Byte Strings

Strings are stored as raw byte sequences rather than text-only characters, which allows them to carry binary data (like cryptographic hashes). A string is encoded by prefixing the raw content with its byte length in base-10, followed by a colon (:).

  • Format: <length>:<string_data>
  • Examples:
    • "torrent" becomes 7:torrent
    • "BitTorrent" becomes 10:BitTorrent
    • An empty string becomes 0:

3. Lists

Lists represent ordered collections of Bencoded elements. A list can contain any combination of data types, including other lists or dictionaries. A list begins with the letter l and ends with e.

  • Format: l<contents>e
  • Examples:
    • A list containing "cat" and "dog": l3:cat3:doge
    • A mixed list with a string, an integer, and an empty list: l4:testi99elee

4. Dictionaries

Dictionaries are associative key-value maps. They begin with the letter d and end with e. In Bencode, every key must be a byte string, and keys must appear in strict lexicographical (binary) order.

  • Format: d<key1><value1><key2><value2>...e
  • Example:
    • A dictionary with keys "age" (value 25) and "name" (value "Alice"): d3:agei25e4:name5:Alicee

The Structure of a Bencoded Torrent File

At its root, every .torrent file is a single Bencoded dictionary. This top-level dictionary contains key-value pairs defining the necessary metadata for downloading and verifying files within the swarm.

The primary keys found within the root dictionary include:

  • announce (Byte String): The URL of the primary tracker managing the swarm.
  • announce-list (List of Lists, Optional): Tiered backup tracker URLs.
  • creation date (Integer, Optional): The creation time of the torrent, expressed as a standard Unix timestamp.
  • created by (Byte String, Optional): The name and version of the software client used to generate the file.
  • comment (Byte String, Optional): A free-text comment or note added by the creator.
  • info (Dictionary): The critical core dictionary containing complete file definitions.

Inside the info Dictionary

The info dictionary defines the contents of the shared payload and operates in one of two modes:

1. Single-File Mode

  • name (Byte String): The suggested filename.
  • length (Integer): The total size of the file in bytes.
  • piece length (Integer): The size of each data piece in bytes (commonly powers of two, such as 262,144 for 256 KB or 524,288 for 512 KB).
  • pieces (Byte String): A single concatenated string containing the 20-byte SHA-1 hash for every individual piece in the file.

2. Multi-File Mode

  • name (Byte String): The suggested directory name where all files will reside.
  • piece length (Integer): The byte size of each piece across the entire dataset.
  • pieces (Byte String): The concatenated 20-byte SHA-1 hashes of all pieces.
  • files (List of Dictionaries): A list where each entry defines a file with:
    • length (Integer): The file size in bytes.
    • path (List of Byte Strings): The relative path elements (e.g., l6:folder8:file.mp4e resolves to folder/file.mp4).

Canonical Representation and the Info Hash

Bencode enforces strict determinism. Because dictionary keys must be sorted lexicographically and integers cannot have extraneous padding (such as leading zeros), a given set of metadata will always serialize into the exact same sequence of bytes.

This deterministic property is essential for generating the Info Hash:

  1. The client extracts the raw, serialized Bencoded byte stream of the info dictionary.
  2. The client calculates the 20-byte SHA-1 cryptographic hash of this exact byte sequence.
  3. The resulting hash serves as the universally unique identifier for the torrent across trackers, DHT (Distributed Hash Table) networks, and peer exchanges.