729442eea8d8548842a6e0947e333c7b

The BitTorrent .torrent file format uses Bencode, so this program allows you to unpack .torrent files into something more intelligible. Note that the hashes are in binary, so be sure to escape the output before writing it to your terminal!

#!/usr/bin/perl -w
package Bdecode;
use strict;
use Carp;

our %bdecode_funcs = (
    list => sub {return [bdecode_list($_[0])]},
    dict => sub {return {bdecode_list($_[0])}},
    int => sub {return 0 + $_[1]},
    string => sub {return substr ${$_[0]}, 0, $_[1], ''},
);

# on return, contains unparsed text
sub bdecode(\$) {
    my ($str) = @_;
    my $key =
        $$str =~ /^l/ ? 'list' :
        $$str =~ /^d/ ? 'dict' :
        $$str =~ /^i(0|-?[1-9]\d*)e/ ? 'int' :
        $$str =~ /^(0|[1-9]\d*):/ ? 'string' :
        undef;
    $key or croak 'invalid sequence';
    $$str =~ s///;
    return $bdecode_funcs{$key}->($str, $+);
}

sub bdecode_list($) {
    my ($str) = @_;
    my @result;
    push @result, bdecode($$str) while $$str !~ /^e/;
    $$str =~ s///;
    return @result;
}

1;
#!/usr/bin/perl -w0777
use strict;
use Bdecode;
use Data::Dumper;

my $input = <STDIN>;
my $obj = Bdecode::bdecode($input);
push @ARGV, '' unless @ARGV;
for my $path (@ARGV) {
    my $cur = $obj;
    for my $item (split '/', $path) {
        my ($name, @indices) = split /:/, $item;
        $name =~ s/%([[:xdigit:]]{2})/chr hex $1/eg;
        $cur = $cur->{$name} if length $name;
        $cur = $cur->[$_] for @indices;
    }
    my $dumper = new Data::Dumper([$cur], [$path]);
    print $dumper->Dump;
}

Refactorings

No refactoring yet !

Your refactoring





Format Copy from initial code

or Cancel