I found a script online that did similar, and edited it around a bit. (I added the portion to split the file on disk and hash check it.)
#!/usr/bin/perl $|++; use Bencode qw/bdecode/; use Digest::SHA1 qw(sha1_hex); my $base = shift @ARGV; my $torrent = "$base.torrent"; open( T, $torrent) or die $!; my $torrent_data = join '', <T>; close( T ); my $metainfo = bdecode( $torrent_data ); my $file_name = "$base/" . $metainfo->{'info'}->{'name'}; my $file_length = $metainfo->{'info'}->{'length'}; my $piece_length = $metainfo->{'info'}->{'piece length'}; my $pieces = $metainfo->{'info'}->{'pieces'}; my @pieces = (); my $offset = 0; while ( $offset < length( $pieces ) ) { my $piece = substr( $pieces, $offset * 20, 20 ); push @pieces, $piece; $pieces = substr($pieces,20); } my $path = "C:/users/caleb/desktop/"; open( F, "<", $path . $file_name ) or die "Cannot open file - (Tried t +o open $path$file_name and got this error : $!\n"; print "MyFile - $path$file_name\n"; my $counted = 0; foreach my $p ( @pieces ) { $counted++; $p =~ s/(.)/sprintf("%02x",ord($1))/egs; print "[dothis:] Piece $counted: $p \n"; my ($buf, $data, $n); binmode F; $excount; while ($n = read (F, $data, $piece_length) != 0) { $excount++; print "[dothat] Hash2:" . sha1_hex($data) . "\n\n"; $countpieces = $#pieces; print "Piece Count: $countpieces\n"; print "N = $n\n"; print "DataCount:" . length($data) . "\n"; print "Count:" . $excount . "\n"; print "Counted: $counted\n"; print "Hash:" . sha1_hex($p) . "\n\n"; print "HashMatch!\n" if ($p eq sha1_hex($data)); print "No Match!\n" if ($p ne sha1_hex($data)); print "----------------------\n"; $buf .= $data; } } close( F );
Now, my intended goal was for the script to compare the pieces from the .torrent file against the file stored on disk, one piece at a time, and if the hashes matched let the user know.
The problem is that the script will only output the following -
MyFile - C:/users/caleb/desktop/test/testfile.mp3 [dothis:] Piece 1: c0ba18a0db37c7d6c8c4c267355627dd5b98473f [dothat] Hash2:c0ba18a0db37c7d6c8c4c267355627dd5b98473f Piece Count: 1192 N = 1 DataCount:32768 Count:1 Counted: 1 Hash:ab50b58f162501072fe1ad6c2120e92eba500afd HashMatch! ---------------------- [dothat] Hash2:d902928543f3e0aa4092534c075957e800a5e3c6 Piece Count: 1192 N = 1 DataCount:32768 Count:2 Counted: 1 Hash:ab50b58f162501072fe1ad6c2120e92eba500afd No Match! ---------------------- ....(Edited to not include 1192 data entries).. .... .... [dothat] Hash2:5402f35d944e62bfc750e5a8b5f3be6e84f6cb3b Piece Count: 1192 N = 1 DataCount:31663 Count:1193 Counted: 1 Hash:ab50b58f162501072fe1ad6c2120e92eba500afd No Match! ---------------------- [dothis:] Piece 2: d902928543f3e0aa4092534c075957e800a5e3c6 [dothis:] Piece 3: 1bf32c88a4d6ba89223dfbc680a310c805e54e66
Now, the hashes all match up, but unfortunately the script is not running as it should. 'dothis' should be executing along with 'dothat', but doesn't run until after 'dothat' finishes.
I realize that the while loop is ran once the first piece is counted ($p), and then the script continues the while loop until it finishes and then goes back up. (This is obvious by the logfile - 'Hash:', and 'Counted' never change, where Hash: should be matching with the Hash2: in the logfile, and printing HashMatch, and the Counted: section should be matching Count:).
What I don't understand is WHY, since it's in a foreach loop first and $p should increment with every iteration of the while loop, correct? I also don't understand how to fix this, and I have tried several different things, including moving around the } towards the end to see if possibly I had put them in the wrong spots, as well as adding dothis and dothat in subroutines at one point, and calling them from each other. Aside from changing the order that these two run in, I still get the same results with every change I try to make. During the first round of edits, I had a problem where every single run would increase the size of $p, to the point where it's length went over 250 characters, and grew with every iteration.
I appreciate all the help, and after a week of trying to figure out what I am doing wrong (and going through about 12 different Perl books that I own), I am stumped.
In reply to Foreach/While - Why does this run AFTER that? by CalebH
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |