in reply to de-interleaving binary data
use strict; use warnings; my @masks = map 2**$_, 0..15; sub deinterlace { my $data = shift; my ($odd, $even) = (0, 0); $odd |= ($data & $masks[$_*2 ]) >> $_ for (0..7); $even |= ($data & $masks[$_*2+1]) >> ($_+1) for (0..7); [pack('C', $odd), pack('C', $even)]; } # Build lookup table my @lut; $lut[$_] = deinterlace($_) for (0..0xffff); # Example data my @d = unpack('S*', 'Some data to de-interlace.'. "\xfa" x 6 . "\0" x + 6); printf "%04x ", $_ for @d; print "\n"; # Building output strings my ($odd, $even) = ('', ''); for (@d) { my @bytepair = @{$lut[$_]}; $odd .= $bytepair[0]; $even .= $bytepair[1]; } printf "Lengths: %d and %d\n", length($odd), length($even); printf "%02x ", $_ for unpack('C*', $odd); print "\n---\n"; printf "%02x ", $_ for unpack('C*', $even); print "\n";
|
|---|