Bencode(3pm)

πŸ“¦
version 1.502 Β· 6 versions
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸ’– Bencode β€” bestie's guide to the BitTorrent serialisation format πŸ’–

okay so this is Bencode, a lil Perl module from the User Contributed Perl Documentation corner of the world, and it's literally the whole BitTorrent serialisation format in one adorable package. sit down, grab a strawberry, we're doing this πŸ“


✨ NAME ✨

Bencode β€” the BitTorrent serialisation format. that's it, that's the name, no notes πŸ’…


🌸 SYNOPSIS 🌸

use Bencode qw( bencode bdecode );

my $bencoded = bencode { 'age' => 25, 'eyes' => 'blue' };
print $bencoded, "\n";
my $decoded = bdecode $bencoded;

see how easy?? encode a hash, print it, decode it right back. it's giving effortless πŸ¦‹


πŸŽ€ DESCRIPTION πŸŽ€

this module implements the BitTorrent bencode serialisation format, exactly as it's described in <http://www.bittorrent.org/beps/bep_0003.html#bencoding>. that's the vibe. that's the whole assignment. periodt ✨


πŸ‘‘ INTERFACE πŸ‘‘

πŸ’œ bencode( $datastructure [, $undef_mode ] )

so you hand it data to encode β€” one single argument β€” and that argument can be a scalar, OR a reference to a scalar, an array, or a hash. and bestie, arrays and hashes can contain values of those exact same types too. it's references all the way down, iykyk πŸŒ€

now here's the fun part: plain scalars that look like canonically represented integers get serialised as integers. that's a heuristic, it's just guessing. so if you wanna bypass the guess and force it to be treated as a string, wrap it in a reference to a scalar. πŸ’…

the second argument? totally optional, and if you don't pass it, it defaults to str. it tells the module how to treat undef values. three options, pick your fighter:

  • str β€” encodes undefs as empty strings
  • num β€” encodes undefs as zeroes
  • die β€” croaks the moment it runs into an undef value. dramatic, honestly πŸ’€

and yeah, it croaks on unhandled data types. don't test it. (or do, but know what's coming.)

πŸ¦‹ bdecode( $string [, $do_lenient_decode [, $max_depth ] ] )

feed it a string, it gives you back the corresponding deserialised data structure. chef's kiss 🫢

pass a true value as the second option and it'll disregard the sort order of dict keys. technically that's a violation of the bencode format, but ngl it's somewhat common out there in the wild, so here's your escape hatch. πŸ™ˆ

pass an integer as the third option and it'll croak when it tries to parse dictionaries nested deeper than that level β€” that's your anti-DoS shield against maliciously crafted input. protect yourself, bestie. πŸ›‘οΈ

croaks on malformed data. obviously. ✨


πŸ’€ DIAGNOSTICS πŸ’€

every error message here uses %s to tell you where it happened. let's go through them one by one:

  • trailing garbage at %s β€” your data doesn't end after the first bencode-serialised item. you've got leftovers. also, fun fact, you can get this error if a malformed item follows instead. πŸ™ƒ
  • garbage at %s β€” your data is malformed. that's it, that's the whole diagnosis.
  • unexpected end of data at %s β€” your data is truncated. it just stops. mid-thought. πŸ’€
  • unexpected end of string data starting at %s β€” your data includes a string that declares itself longer than the data you actually have. it's lying to you. 😭
  • malformed string length at %s β€” your data had a string with a negative length, or a length with leading zeroes. neither of those is allowed, bestie.
  • malformed integer data at %s β€” something was supposed to be an integer but didn't make sense. it's giving nonsense.
  • dict key not in sort order at %s β€” your data violates the bencode format constraint that dict keys must appear in lexical sort order. (unless you passed that lenient flag, obviously.)
  • duplicate dict key at %s β€” your data violates the bencode format constraint that all dict keys must be unique. no duplicates. that's the rule.
  • dict key is not a string at %s β€” your data violates the bencode format constraint that all dict keys have to be strings. sorry.
  • dict key is missing value at %s β€” your data contains a dictionary with an odd number of elements. someone didn't bring a partner to the dance. 😭
  • nesting depth exceeded at %s β€” your data contains dicts or lists nested deeper than the $max_depth you passed to bdecode(). too deep, babe. 🌊
  • unhandled data type β€” you're trying to serialise a data structure made of things that aren't:
    • scalars
    • references to arrays
    • references to hashes
    • references to scalars

the format simply does not support that, and it's not gonna pretend to. πŸ’…


πŸ› BUGS AND LIMITATIONS πŸ›

okay so real talk: in Perl, strings and numbers are practically indistinguishable. like, genuinely. so bencode() has to resort to a heuristic to decide how to serialise a scalar, and there is no way to fix this. it cannot be fixed. this is forever. we live here now. 😭


🌈 AUTHOR 🌈

Aristotle Pagaltzis <pagaltzis@gmx.de> β€” iconic behavior, honestly πŸ‘‘


this software is copyright (c) 2017 by Aristotle Pagaltzis.

this is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. slay πŸ’–


and that's the whole page, bestie!! perl v5.34.0, dated 2022-08-18 β€” go forth and bencode responsibly πŸŽ€βœ¨πŸ¦‹πŸ’…

πŸ“¦ where this page comes from