On 5/20/24 11:01, Roman Perepelitsa
wrote:
On Mon, May 20, 2024 at 7:41 PM Kannan Varadhan <kvaradhan3@xxxxxxxxx> wrote:
while (( $#bytes < 4 )); do
sysread -s$((4-$#bytes)) 'bytes[$#bytes+1]' </dev/urandom || return
done
Reading 1 byte at a time is slower than reading 4 bytes at once.
ok but the loop seems to read 4, then 3, 2, and 1B in each
iteration, or did I miss something?
To clarify this, it has to do with the way sysread assigns to the parameter 'bytes[$#bytes+1]'.
On the first iteration, $#bytes == 0, so this is 'bytes[1]'. Assignment to a subscripted parameter reference replaces the element at the subscript position (or positions, if a range is given, which is not allowed for associative arrays) with the assigned value. Thus all bytes returned from /dev/urandom in the first read are inserted in place of position 1 in the string bytes. There's nothing at position 1 yet in this case, so that becomes the entire value of $bytes. If fewer than 4 bytes were returned -- say, 2 -- then at the next iteration we sysread into bytes[3], which is past the end of the existing 2-byte value, so has the effect of appending the next series of bytes and lengthening the string.
Upshot: The loop attempts to read the exact number of (remaining) bytes necessary to fill a four-byte string, and repeatedly appends if and only if it doesn't yet have all four.