use strict ; use warnings ; #1234567890123456789012345678901234567890123456789012345678901234 my $vlans = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' .'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' .'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' .'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe' ; my $vlan_vec = to_vec($vlans) ; # Convert long hex integer to bit-vector # VLAN numbers are mapped to/from $vlan_vec by vec($vlan_vec, 1, $vn) # This scans the bit-vector looking for ranges of VLAN numbers. # # Note that we can read one bit beyond the given range, and get 0 my $r = undef ; my @s = () ; for my $vn (0..length($vlan_vec) * 8) { if (vec($vlan_vec, $vn, 1)) { if (!defined($r)) { push @s, "$vn.." ; } ; $r = $vn ; } else { if (defined($r)) { $s[-1] .= "$r" ; $r = undef ; } ; } ; } ; print "Ranges: ", join(', ', @s), "\n" ; # Convert long hex integer to bit-vector. # # Combination of 'h*' and reverse gives bits in right order in the bit-vector. sub to_vec { my ($hex) = @_ ; $hex =~ s/^0x// ; return pack('h*', scalar reverse $hex) ; } ; # Convert bit-vector to long integer. Again 'h*' and reverse sorts out bit order. sub from_vec { my ($vec) = @_ ; return '0x'. scalar reverse(unpack('h*', $vec)) ; } ;