use Data::Dumper; # Input data my %data = ( 1 => [qw/I don't know/], 2 => [qw/what to use/], 3 => [qw/as values !/] ); # Repeat multiple times: # A signed 32 bit integer followed by three null terminated strings my $pattern = "(l(Z*)3)*"; # Encoding my $packed = pack $pattern, map { $_, @{$data{$_}} } keys %data; # Decoding my @unpacked = unpack $pattern, $packed; my ($key, @values, %out); $out{$key} = [@values] while (($key, @values) = splice @unpacked, 0, 4); print Dumper \%out;