in reply to $str to %hash to @ary

Here's another method that doesn't use a hash at all (since the hash appears to be a synthetic variable not related to the problem you're trying to solve).

my $str="17:43:33:21:23:19:27:6"; my @a = split/:/,$str; @a % 2 && die; # not an even number of items while (my ($p,$ad) = splice @a,0,2) { push @ary, ($ad) x $p; } my $adId=$ary[int(rand(100))];

Basically it just splits the string into an array, then grabs elements 2 at a time from the array until the array is exhausted. The code also makes use of the repetition operator in list context to get the ads repeated the proper number of times.