Skip to content

Instantly share code, notes, and snippets.

@mwgamera
Last active December 25, 2015 09:10
Show Gist options
  • Select an option

  • Save mwgamera/0cd5a032c07447887426 to your computer and use it in GitHub Desktop.

Select an option

Save mwgamera/0cd5a032c07447887426 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
# Convert Torrent files between Bencode and YAML
# klg, May 2014
use strict;
use open ':std', IO => ':bytes';
use Digest::SHA 'sha1_hex';
use Bencode qw/bencode bdecode/;
use YAML;
my $data = do { local $/; <> };
if (my $bdat = eval { bdecode $data } ) {
if (ref $bdat->{info}) {
my $info = $bdat->{info};
printf "# btih:%s\n", sha1_hex bencode $info;
if ($info->{pieces}) {
my $pieces = $info->{pieces};
warn "info.pieces should be a string\n" if ref $pieces;
delete $info->{pieces};
$info = YAML::Node->new($info);
$info->{pieces} = YAML::Node->new([
unpack '(H40)*', "$pieces"
], '!torrent/info.pieces');
}
delete $bdat->{info};
$bdat = YAML::Node->new($bdat);
$bdat->{info} = $info;
}
$data = Dump $bdat;
$data =~ s/(\n\s*)-\s*\1\s+- (\S*)(?=\1-|\n[^\s-])/$1- [ $2 ]/g;
print $data;
} elsif (my $ydat = eval { Load $data }) {
if ($ydat->{info} && $ydat->{info}->{pieces}) {
if ('ARRAY' eq ref $ydat->{info}->{pieces}) {
$ydat->{info}->{pieces} = pack '(H40)*', @{$ydat->{info}->{pieces}};
} else {
warn "info.pieces should be a sequence\n";
}
}
print bencode $ydat;
} else {
die "Failed to parse as YAML or Bencode\n";
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment