$r = rand($sum); foreach (keys(%data)) { if ($r < $data{$_}) { $select = $_; last} $r -= $data{$_}; }

キーの数が十分少なければこれでいけると思う。一種のバカサーチなのでキーの数が
たくさんあるときは二分法ぽくするとかもう一工夫したいところ。