Perl解析ISC DHCP日志生成HTML表的IP地址排序问题求助
Perl IP地址数值排序修复方案
问题原因
现有代码使用字符串比较运算符cmp排序IP,字符串会逐位对比ASCII值,192.168.250.149的第12位字符为1,ASCII值小于192.168.250.2第12位的2,因此出现排序异常。此外原代码sort后直接跟%data属于逻辑错误,会将哈希的键、值全部放入排序队列,需要修正为取哈希的键keys %data排序。
修复代码
方案1:直接拆分比较(适合小数据量场景)
直接在排序块内拆分IP为四段,按每段数值依次比较:
my @sorted = sort { my @a_parts = split /\./, $data{$a}{'ip'}; my @b_parts = split /\./, $data{$b}{'ip'}; $a_parts[0] <=> $b_parts[0] || $a_parts[1] <=> $b_parts[1] || $a_parts[2] <=> $b_parts[2] || $a_parts[3] <=> $b_parts[3] } keys %data;
方案2:施瓦茨变换(适合大数据量场景)
提前拆分IP缓存结果,避免每次比较都重复拆分IP,排序效率更高:
my @sorted = map { $_->[0] } sort { $a->[1] <=> $b->[1] || $a->[2] <=> $b->[2] || $a->[3] <=> $b->[3] || $a->[4] <=> $b->[4] } map { [ $_, split /\./, $data{$_}{'ip'} ] } keys %data;
两种方案都可以实现IPv4地址按四段数值自然排序,不会再出现高数值后缀IP排在低数值前面的问题。
内容的提问来源于stack exchange,提问作者HugoBoss
相关产品推荐
相关产品推荐

