有没有更有效的方法在Perl中生成随机文件?

时间:2010-08-10 00:42:42

标签: perl file-io random

这是我的第一个Perl脚本。曾经:

#!/usr/bin/perl

if ($#ARGV < 1) { die("usage: <size_in_bytes> <file_name>\n"); }

open(FILE,">" . $ARGV[0]) or die "Can't open file for writing\n";

# you can control the range of characters here
my $minimum = 32;
my $range = 96;

for ($i=0; $i< $ARGV[1]; $i++) {
    print FILE chr(int(rand($range)) + $minimum);
}

close(FILE);

其目的是generate a file in a specified size filled with random characters

它有效,但速度很慢。写一个10MB的随机文件需要几秒钟 有没有人有关于如何更快/更好的建议/提示?也可以随意指出常见的新手错误。

3 个答案:

答案 0 :(得分:6)

  1. 每次调用时,您都可以要求rand为您创建多个值。
  2. 在致电print之前收集多个字符。一次打印一个字符效率很低。
  3. for (my $bytes = 0; $bytes < $num_bytes; $bytes += 4) {
        my $rand = int(rand($range ** 4));
        my $string = '';
        for (1..4) {
            $string .= chr($rand % $range + $minimum);
            $rand = int($rand / $range);
        }
        print FILE $string;
    }
    

答案 1 :(得分:5)

从/ dev / random写入流数据。

#!/usr/bin/perl
use File::Copy;
if ($#ARGV < 1) { die("usage: <size_in_bytes>\n"); }
copy("/dev/random","tmp", $ARGV[0]) or die "Copy failed: $!";

代码未经过测试。

修改 由于您需要一个范围,请执行此操作。

您的范围在96到32之间,这是64.64 = 01000000b(十六进制为0x40)的空间。 只需生成数字,然后按照要生成的值范围的数字进行按位AND,并通过预先形成与其值(00100000b或0x20)的按位OR来添加下限

这可以让你做任何随机字符串(只需从/ dev / random读取原始十六进制)并将数据转换为你的范围。

答案 2 :(得分:1)

如果你需要一个范围内的随机数,我不知道更有效的方法。你的脚本根据我的喜好调整:

#!/usr/bin/perl

use warnings;
use strict;

die("usage: $0 <size_in_bytes> <file_name>\n") unless @ARGV == 2;

my ($num_bytes, $fname) = @ARGV;

open(FILE, ">", $fname) or die "Can't open $fname for writing ($!)";

my $minimum = 32;
my $range = 96;

for (1 .. $num_bytes) {
    print FILE pack( "c", int(rand($range)) + $minimum);
}

close(FILE);

当我真正需要二进制文件时,我使用pack("c")chr()也可能没问题,但IIRC实际上取决于你的环境使用的字符编码是什么(想想ASCII与utf8。)

顺便说一下,如果你真的需要二进制文件来兼容Windows,你可能想在binmode FILE;之后添加open

否则,如果范围是可选的,您可以简单地dd if=/dev/random of=$filename bs=1 count=$size_of_the_output(或者在Linux上使用更快的加密不安全/dev/urandom)。但是当/dev/random真正尝试传递真正的随机位时,这会慢得多 - 因为它们变得可用。如果没有足够的(例如你的平台没有H / W RNG)那么性能真的会受到影响 - 与速度极快的libc的伪随机数生成器相比(Perl在内部使用来实现{{1} })。