srand( time() ^ ($$ + ($$ << 15)) );
如果用于加密目的,那么你需要用比缺省的生成更随机的算法。有些系统上有 /dev/random 设备就比较合适,否则,拿一个或多个会迅速改变操作系统状态的程序的输出,压缩以后进行校验和计算是常用的方法。比如:
srand (time ^ $$ ^ unpack "%32L*", `ps wwaxl | gzip`);
如果你特别关心这些问题,那么请参阅 CPAN 上的 Math::TrulyRandom 模块。
不要在你的程序里多次调用 srand,除非你知道你在干什么并且知道为什么这么做。这个函数的目的是给 rand 函数,这样 rand 就可以在你每次运行你的程序的时候生成不同的序列。只需要在你的程序开始做一次,否则你就不能从 rand 中获得随机的数值!
stat FILEHANDLE
stat EXPR
stat
在标量环境里,这个函数返回一个布尔值,该值表示调用是否成功。在列表环境里,它返回一个 13 个元素的列表,给出一个文件的统计信息,该文件要么是通过 FILEHANDLE 打开,要么是用 EXPR 命名。它的典型应用如下:
($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
$atime, $mtime, $ctime, $blksize, $blocks)
= stat $filename;
不是在所有文件系统类型上都支持这些域;不支持的域返回 0。表 29-5 列出了各个域的含义。
表 29-5。stat 返回的域
$dev 和 $ino 放在一起,在同一个系统里唯一地标识一个文件。$blksize 和 $blocks 很可能只在 BSD 衍生出的文件系统里有。如果有 $block 域,那么它是以 512 字节的块汇报的。$blocks*512 的值可能和 $size 差距相当大,因为有些文件包含未分配的块,或者说“洞”,它们没有在 $blocks 中计算。
如果传递给 stat 一个特殊的文件句柄,该句柄里包含下划线,那么就不会做实际的 stat(2)调用,而是返回上一次 stat,lstat,或者基于 stat 的文件测试操作符(比如 -r,-w,和 -x)的 stat 结构。
因为模式包含文件类型及其权限,所以如果你想看真正的权限,那么你应该屏蔽掉文件类型部分,并且在 printf 或者 sprintf 里用“%o”:
$mode = (stat($filehane))[2]; printf "Permissions are %04o\n", $mode &07777;
File::stat 模块提供一个方便的通过名字访问的机制:
use File:;stat;
$sb = stat($filename);
printf "File is %s, size is %s, perm %04o, mtime %s\n",
$filename, $sb->size, $sb->mode & 07777,
scalar localtime $sb->mtime;
你还可以从 Fcntl 模块里输入各种不同模式位的符号定义。参阅联机文档获取更多细节。
提示:如果你只需要文件尺寸,那么可以用 -s 文件测试操作符,它直接返回以字节计的文件大小。另外还有返回以天计的文件年龄的文件测试。
study SCALAR
study
这个函数花了一些额外的时间用在研究 SCALAR 上,预测在进行下一次修改之前要做的匹配次数。这么做也许能但也许不能节约时间,具体情况取决于你正在搜索的模式的天性和数量,以及待搜索字串中字符出现频率的分布——你可能需要比较有它和没它的运行时间来看看哪个运行得快一些。那些扫描许多常量字串(包括在更复杂的模式里的常量部分)的循环会从 study 中得到最大好处。如果你的所有模式匹配都是前面有锚符号的常量字串,那么 study 一点忙都帮不上,因为那里没有扫描。你每次只能拥有一个 study——如果你研究另外一个标量的话,那么前面那个就“没有研究”了。
study 运转的方法是:做一个包含待搜索字串中的每个字符的链表,因此,打个比方,我们就知道了所有的“k”字符的位置。从每个搜索字串里选出最少见的字符,这是基于从一些 C 程序和英文文本构造出来的频率统计表的。只对那些包含这个最少见字符的位置进行检查。
比如,下面是一个循环,它在每个包含特定模式的行前面插入一个生成索引的记录:
while(<>) {
study;
print ".IX foo\n" if /\bfoo\b/;
print ".IX bar\n" if /\bbar\b/;
print ".IX blurfl\n" if /\bblurfl\b/;
...
print;
}
为了搜索 /\bfoo\b/,只查看 $_ 里的那些包含“f”的位置,因为“f”比“o”少见。除了在病态的情况下,这样做是很有优势的。唯一的问题是它是否能节约比先制作链表花的时间更多的时间。
如果你必须搜索那些你直到运行时才知道的字串,那么你可以把整个循环作成一个字串然后 eval 它以避免每次都要重新编译你的模式。再通过设置 $/ 把整个文件输入成一条记录,把这些组合起来可以非常快,通常比那些程序,象 fgrep(1) 什么的都快。下面的程序扫描一个文件列表(@files),搜索一个单词列表(@words),并且把那些包含大小写无关匹配的文件名字打印出来:
$search = 'while (<>) { study;';
foreach $word (@words) {
$search .= "++\$seen{\$ARGV} if /\\b$word\\b/i;\n";
}
$search .= "}";
@ARGV = @files;
undef $/; # 吃进整个文件
eval $search; # 这里运行程序
die $@ if $@; # 处理 eval 失败
$/ = "\n"; # 恢复正常的输入终止符
foreach $file (sort keys(%seen)) {
print "$file\n";
}
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-28372-14.html
再个地方政府保护当地企业也很正常