它有什么写得不好的地方吗?它可能需要更好的变量名称,但我不知道是否可能(因为中间步骤似乎没有可命名的特征),只剩下了对 split
方法的不恰当使用。 伪代码几乎是逐字翻译。
$a = $ARGV[0];
$a =~ s/[^A-F0-9]+//simg;
@b = reverse split /(\S{2})/,$a;
$c = join "", @b;
$c .= "0000";
$d = hex($c) % 999999929;
print "$d\n";
应该是这样的
$a = $ARGV[0];
$a =~ s/[^A-F0-9]+//simg;
@b = reverse $a =~ /(..)/sg;
$c = join "", @b;
$c .= "0000";
$d = hex($c) % 999999929;
print "$d\n";
稍微更清楚一些:
$a = $ARGV[0];
$a =~ s/[^0-9A-Fa-f]+//g;
$a = join '', reverse $a =~ /(..)/sg;
$a .= "0000";
$a = hex($a);
$a %= 999999929;
print "$a\n";
这些代码片段可能存在问题。在具有32位整数的Perl中,如果输入的十六进制数超过4个数字,
hex
将会溢出。而具有64位整数的Perl可以处理12个十六进制数字。
你似乎是从
这里获取了代码。它旨在以MAC地址作为输入,这意味着代码需要64位整数或
Math::BigInt才能工作。由于您想模除64位值,因此没有绕过它的方法。
以下是一种简洁的方法,仅适用于具有64位整数的Perl:
my $mac = $ARGV[0];
$mac =~ s/[^0-9A-Fa-f]+//g;
die length($mac) != 12;
my $hash = unpack('Q<', pack('H*', "0000$mac"));
$hash %= 999999929;
print "$hash\n";
为了提高可移植性,最好将Math::BigInt集成到早期版本中。
s///
和split
,其中第一个参数不清楚。与其使用位移操作,不如在末尾拼接零。甚至s///
都很愚蠢。应该只使用s/[[:^xdigit:]]+//g
。/s
和/m
选项没有影响。 - Sinan Ünür