sub good_karma { my $raw_bytes = shift; my @raw_bytes = unpack 'C*', $raw_bytes; # unsigned char / 8 bits my @temp_bytes; my @resultant_bytes; my $i = 7; for my $byte (@raw_bytes) { $i++; if ($i == 8) { # this is one of those 'fill-in' rows, so dump # out the temp_bytes and re-init them push @resultant_bytes, @temp_bytes[1...7]; # my unpack is a little rusty - this should result # in 8 array elements - each 1 or 0 (with the first always 0) my @seven_bits = unpack 'bbbbbbbb', $byte; # shift the bit to the left. 8 <<'s might be faster $temp_bytes[$_] = $seven_bits[$_] * 128 for 1...7; # @temp_bytes is now (0, A0000000, B00000000, ...) # restart counter each time $i = 1; } # the 7 bit bytes are conveniently left 0 padded, so we # can just or the two parts together $temp_bytes[$i] |= $byte; } # handle final loop end-case push @resultant_bytes, @temp_bytes[1...$i]; return join( '', @resultant_bytes ); }