use strict; srand(2); # create a random string of 1's and 0's (string length = $l) sub make_rand_str{ my ($l) = @_; if ($l%8!=0){ print STDERR "not a divider of a byte 8-bits)\n"; die; } my $res = ''; for (1..$l){ $res .= int(rand(2)); } return $res; } # take a string and randomly flip 1's/0's for <= $n number of positions sub flip { my ($n,$str) = @_; my $res = ''; my @str = split("",$str); for (0..($n-1)){ my $i = int(rand(length($str)-1)); $str[$i] = ($str[$i] eq '1' ? '0': '1' ); } return join("", @str); } # pack the string sub pack_str { my ($s) = @_; my $res = ''; my @str = split("",$s); for(my $i=0; $i<@str; $i+=8){ my $st = join("",@str[$i..($i+7)]); $res .= pack('B8',$st); } return $res; } #------------------------Main---------------------# # though the string length here is set to 80 in reality it is anywhere between 300-1000 my $str_len = 80; my $num_of_flips = int($str_len * 0.25); my $randstr = &make_rand_str($str_len); print $randstr . "\n"; open(UNPACKED,">", "unpacked.str") || die $!; open(PACKED,">:raw", "packed.str") || die $!; for (1..1000){ my $mut_str = &flip($num_of_flips,$randstr); print UNPACKED "$mut_str\n"; my $packed_str = &pack_str($mut_str); print PACKED "$packed_str"; } close UNPACKED; close PACKED; system("cat unpacked.str | gzip -9 -c - > unpacked.str.gz"); system("cat packed.str | gzip -9 -c - > packed.str.gz"); #### bytes file ----------------- 11000 packed.str 9979 packed.str.gz 81000 unpacked.str 12777 unpacked.str.gz