这是我的第一个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的随机文件需要几秒钟 有没有人有关于如何更快/更好的建议/提示?也可以随意指出常见的新手错误。
答案 0 :(得分:6)
rand
为您创建多个值。print
之前收集多个字符。一次打印一个字符效率很低。
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} })。