I have to spell this out; perhaps other monks will appreciate the explination. Please feel free to correct me.
rand @chars takes @chars in scalar context, that is, the length of the array holding our characterset. So rand returns a value somewhere in the array, and that becomes the index for the array lookup.
I keep forgetting you can do cool things like this by implied scalar or array context.
Don't forget to add that using a floating point number as an array index, does an implied int on the value. In other words: it truncates towards zero. $a[5.9] is the same array element as $a[5], not$a[6].