DB_File problem

DB_File problem

am 18.08.2005 10:18:22 von evlong

I am working on a script to base64 encode a file and then scramble the
lines but also keep track of the order in which these lines were
scrambled. Anyway, the problem occurs when I untie and undef all
references to the file. After all references are destroyed, the file
that was referenced ends up rewriting itself.

So here is a flow of the program:
1.Base64 encode the file passed at the command line.
2.Randomly swap lines in the file and store the pairs (line numbers)
that were swapped for later use.
3.Then get rid of all references to the base64 encoded file (This is
were the rewrite of the entire file occurs).
4.Then save the pairs that were swapped to a file for use when
descrambling the encoded file.

This is probably a dumb question but I would appreciate any help I can
get.

The source follows:

#scramble.pl
#ARGV[0] is the source file
#ARGV[1] name of the file that is encoded
#ARGV[2] is the order file

use MIME::Base64;
use DB_File;

open(IN, $ARGV[0]);
open(OUT, ">".$ARGV[1]);
binmode IN;
while(read(IN, $buffer, 4104)){
print OUT encode_base64($buffer);
}
close(OUT);
close(IN);


$db = tie @data, "DB_File", $ARGV[1], O_RDWR, 777, $DB_RECNO;
$length = $db->length;

srand;
for($i=0; $i<$length; $i++){
$index1 = $i;
$index2 = int(rand($length-1));
$db->get($index1, $tmp1);
$db->get($index2, $tmp2);
$db->put($index1, $tmp2);
$db->put($index2, $tmp1);
$order .= $index1.",".$index2."\n";
}
undef $db;
untie @data;
open(ORDER, ">".$ARGV[2]);
print ORDER $order;
close (ORDER);

exit;

Re: DB_File problem

am 18.08.2005 12:07:01 von someone

evlong wrote:
> I am working on a script to base64 encode a file and then scramble the
> lines but also keep track of the order in which these lines were
> scrambled. Anyway, the problem occurs when I untie and undef all
> references to the file. After all references are destroyed, the file
> that was referenced ends up rewriting itself.
>
> So here is a flow of the program:
> 1.Base64 encode the file passed at the command line.
> 2.Randomly swap lines in the file and store the pairs (line numbers)
> that were swapped for later use.
> 3.Then get rid of all references to the base64 encoded file (This is
> were the rewrite of the entire file occurs).
> 4.Then save the pairs that were swapped to a file for use when
> descrambling the encoded file.
>
> This is probably a dumb question but I would appreciate any help I can
> get.
>
> The source follows:
>
> #scramble.pl

You should start your programs with the warnings and strict pragmas to
help you detect mistakes.

use warnings;
use strict;


> #ARGV[0] is the source file
> #ARGV[1] name of the file that is encoded
> #ARGV[2] is the order file
>
> use MIME::Base64;
> use DB_File;
>
> open(IN, $ARGV[0]);

You should *ALWAYS* verify that the file was opened.

open IN, '<', $ARGV[0] or die "Cannot open $ARGV[0]: $!";


> open(OUT, ">".$ARGV[1]);

Yes *ALWAYS*!

open OUT, '>', $ARGV[1] or die "Cannot open $ARGV[1]: $!";


> binmode IN;
> while(read(IN, $buffer, 4104)){

Even though you are requesting to read 4104 bytes that does not mean
that $buffer will contain exactly 4104 bytes so if it makes a difference
you should check for this.


> print OUT encode_base64($buffer);
> }
> close(OUT);
> close(IN);
>
>
> $db = tie @data, "DB_File", $ARGV[1], O_RDWR, 777, $DB_RECNO;

It looks like your problem is that you are setting the file mode to
read-only.

$ ls -l TEST
/bin/ls: TEST: No such file or directory
$ perl -le'use DB_File;tie @data,"DB_File","TEST",O_RDWR,777,$DB_RECNO;'
$ ls -l TEST
-r----x--t 1 john users 0 2005-08-18 02:47 TEST

You should be using the octal number 0777 instead of the decimal number
777 (although why you would need execute permissions on a text file?)

Also you should *ALWAYS* verify that the file opened.

my $db = tie my @data, 'DB_File', $ARGV[1], O_RDWR, 0777, $DB_RECNO
or die "Cannot open $ARGV[1]: $!";

Also it might be easier to use the Tie::File module for this.


> $length = $db->length;
>
> srand;
> for($i=0; $i<$length; $i++){
> $index1 = $i;
> $index2 = int(rand($length-1));

$length is the number of elements in the array so by subtracting one
that means that the last line in the file will never be accessed by $index2.


> $db->get($index1, $tmp1);
> $db->get($index2, $tmp2);
> $db->put($index1, $tmp2);
> $db->put($index2, $tmp1);
> $order .= $index1.",".$index2."\n";
> }
> undef $db;

It shouldn't be necessary to "undef $db" as the following untie destroys
all references.


> untie @data;
> open(ORDER, ">".$ARGV[2]);

You should *ALWAYS* verify that the file was opened.

open ORDER, '>', $ARGV[2] or die "Cannot open $ARGV[2]: $!";


> print ORDER $order;
> close (ORDER);
>
> exit;


John
--
use Perl;
program
fulfillment

Re: DB_File problem

am 18.08.2005 19:45:18 von evlong

Thanks for the help.
John W. Krahn wrote:
> evlong wrote:
> > I am working on a script to base64 encode a file and then scramble the
> > lines but also keep track of the order in which these lines were
> > scrambled. Anyway, the problem occurs when I untie and undef all
> > references to the file. After all references are destroyed, the file
> > that was referenced ends up rewriting itself.
> >
> > So here is a flow of the program:
> > 1.Base64 encode the file passed at the command line.
> > 2.Randomly swap lines in the file and store the pairs (line numbers)
> > that were swapped for later use.
> > 3.Then get rid of all references to the base64 encoded file (This is
> > were the rewrite of the entire file occurs).
> > 4.Then save the pairs that were swapped to a file for use when
> > descrambling the encoded file.
> >
> > This is probably a dumb question but I would appreciate any help I can
> > get.
> >
> > The source follows:
> >
> > #scramble.pl
>
> You should start your programs with the warnings and strict pragmas to
> help you detect mistakes.
>
> use warnings;
> use strict;
>
>
> > #ARGV[0] is the source file
> > #ARGV[1] name of the file that is encoded
> > #ARGV[2] is the order file
> >
> > use MIME::Base64;
> > use DB_File;
> >
> > open(IN, $ARGV[0]);
>
> You should *ALWAYS* verify that the file was opened.
>
> open IN, '<', $ARGV[0] or die "Cannot open $ARGV[0]: $!";
>
>
> > open(OUT, ">".$ARGV[1]);
>
> Yes *ALWAYS*!
>
> open OUT, '>', $ARGV[1] or die "Cannot open $ARGV[1]: $!";
>
>
> > binmode IN;
> > while(read(IN, $buffer, 4104)){
>
> Even though you are requesting to read 4104 bytes that does not mean
> that $buffer will contain exactly 4104 bytes so if it makes a difference
> you should check for this.
>
>
> > print OUT encode_base64($buffer);
> > }
> > close(OUT);
> > close(IN);
> >
> >
> > $db = tie @data, "DB_File", $ARGV[1], O_RDWR, 777, $DB_RECNO;
>
> It looks like your problem is that you are setting the file mode to
> read-only.
>
> $ ls -l TEST
> /bin/ls: TEST: No such file or directory
> $ perl -le'use DB_File;tie @data,"DB_File","TEST",O_RDWR,777,$DB_RECNO;'
> $ ls -l TEST
> -r----x--t 1 john users 0 2005-08-18 02:47 TEST
>
> You should be using the octal number 0777 instead of the decimal number
> 777 (although why you would need execute permissions on a text file?)
>
> Also you should *ALWAYS* verify that the file opened.
>
> my $db = tie my @data, 'DB_File', $ARGV[1], O_RDWR, 0777, $DB_RECNO
> or die "Cannot open $ARGV[1]: $!";
>
> Also it might be easier to use the Tie::File module for this.
>
>
> > $length = $db->length;
> >
> > srand;
> > for($i=0; $i<$length; $i++){
> > $index1 = $i;
> > $index2 = int(rand($length-1));
>
> $length is the number of elements in the array so by subtracting one
> that means that the last line in the file will never be accessed by $index2.
>
>
> > $db->get($index1, $tmp1);
> > $db->get($index2, $tmp2);
> > $db->put($index1, $tmp2);
> > $db->put($index2, $tmp1);
> > $order .= $index1.",".$index2."\n";
> > }
> > undef $db;
>
> It shouldn't be necessary to "undef $db" as the following untie destroys
> all references.
>
>
> > untie @data;
> > open(ORDER, ">".$ARGV[2]);
>
> You should *ALWAYS* verify that the file was opened.
>
> open ORDER, '>', $ARGV[2] or die "Cannot open $ARGV[2]: $!";
>
>
> > print ORDER $order;
> > close (ORDER);
> >
> > exit;
>
>
> John
> --
> use Perl;
> program
> fulfillment