Bug#695285: /etc/cron.daily/apt backup RNG is very wasteful
> Thanks for checking this. I like this, its more compact than the > current code. However the reason why I did not use this, was that the > following fragment: > > $ while true; do res=$(od -N2 -d /dev/urandom | cut -s -d' ' -f2); echo > $res; if [ -z "$res" ]; then break; fi ; done > 61581 > 42056 > 38021 > > $ > > give me a empty string in $res sometimes. I haven't really put any > though into why this is, maybe just a side effect of running it in th > while loop? No, it's a side effect of od printing a decimal number which is sometimes less than 1 and so is space-padded on the left. Try: while : ; do x=$(od -N2 -d /dev/urandom); y=$(echo "$x" | cut -s -d' ' -f2); echo $y; if test -z "$y"; then echo "$x"; break; fi; done When it errors out, $x contains: 000 9611 002 Now is it clear? Include *all* the fields other than 1 and it will never fail: while :; do res=$(od -N2 -d /dev/urandom | cut -s -d' ' -f2-); echo $res; if [ -z "$res" ]; then break; fi ; done The other way is to use a number format that is zero-padded: while :; do res=0x$(od -N2 -x /dev/urandom | cut -s -d' ' -f2-); echo $res; if [ -z "$res" ]; then break; fi ; done -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Bug#695285: /etc/cron.daily/apt backup RNG is very wasteful
On Thu, Jan 10, 2013 at 02:44:42AM -0500, sacrificial-spam-addr...@horizon.com wrote: > > Thanks, I fixed this now in my bzr tree and it will be part of the > > next upload. > > Er, assuming that's revision 2269: > http://anonscm.debian.org/loggerhead/apt/debian-sid/revision/2269/debian/apt.cron.daily Great, thanks for double checking. > You don't need the final "cut -c1-5". It is true that cksum returns an > unsigned 32-bit number, and some shells only do 32-bit signed math, but > they simply convert the number to negative. > > You either mask off the sign bit with > RANDOM=$(($(dd if=/dev/urandom bs=2 count=1 2> /dev/null | cksum | cut -d' ' > -f1) % 0x7fff)) > > Or, of you want to emulate the range of Bash $RANDOM exactly: > RANDOM=$(($(dd if=/dev/urandom bs=2 count=1 2> /dev/null | cksum | cut -d' ' > -f1) % 0x7fff)) Thanks, indeed, simulating this more closely is probably a good idea, I added that in my bzr branch now. > The "od -d -N2 -An" solution works with a recent enough od. > I was looking to see how old that can be. The uppercase option flags > are not in 7th edition, but are in POSIX.1 as of 2001: [..] Thanks for checking this. I like this, its more compact than the current code. However the reason why I did not use this, was that the following fragment: $ while true; do res=$(od -N2 -d /dev/urandom | cut -s -d' ' -f2); echo $res; if [ -z "$res" ]; then break; fi ; done 61581 42056 38021 $ give me a empty string in $res sometimes. I haven't really put any though into why this is, maybe just a side effect of running it in th while loop? Cheers, Michael -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Bug#695285: /etc/cron.daily/apt backup RNG is very wasteful
> Thanks, I fixed this now in my bzr tree and it will be part of the > next upload. Er, assuming that's revision 2269: http://anonscm.debian.org/loggerhead/apt/debian-sid/revision/2269/debian/apt.cron.daily You don't need the final "cut -c1-5". It is true that cksum returns an unsigned 32-bit number, and some shells only do 32-bit signed math, but they simply convert the number to negative. You either mask off the sign bit with RANDOM=$(($(dd if=/dev/urandom bs=2 count=1 2> /dev/null | cksum | cut -d' ' -f1) % 0x7fff)) Or, of you want to emulate the range of Bash $RANDOM exactly: RANDOM=$(($(dd if=/dev/urandom bs=2 count=1 2> /dev/null | cksum | cut -d' ' -f1) % 0x7fff)) The "od -d -N2 -An" solution works with a recent enough od. I was looking to see how old that can be. The uppercase option flags are not in 7th edition, but are in POSIX.1 as of 2001: http://www.unix.com/man-page/posix/0/od/ It also appears to be in xpg4: http://docs.oracle.com/cd/E19963-01/html/821-1461/od-1.html And in SunOD 5.8 (2000): http://www.manpages.info/sunos/od.1.html GNU textutils 2.0 (1999): http://sunsite.ualberta.ca/Documentation/Gnu/textutils-2.0/man/od.1.html Apparently the spec was in POSIX.1 as of 1992, alyhough not NetBSD as of 2000: http://gnats.netbsd.org/11204 It was added to NetBSD in 2008: http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.bin/hexdump/od.1?rev=1.23&content-type=text/x-cvsweb-markup&f=H&only_with_tag=MAIN -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Bug#695285: /etc/cron.daily/apt backup RNG is very wasteful
On Thu, Dec 06, 2012 at 11:45:40AM -0500, sacrificial-spam-addr...@horizon.com wrote: > Package: apt > Version: 0.9.7.6 > Severity: minor Thanks for your bugreport. [..] > This backup for a missing $RANDOM reads 512 bytes out of /dev/urandom, only > to reduce it (incorrectly) to a 5-digit number (16.6 bits max, although > the distribution is skewed), then to 10.8 bits (modulo 1800). > > It's incorrect because cksum produces a 32-bit checksum, formatted as > "%u", so some small fraction of the time (1 in 4.3 million times), it'll > be less than 1000 and the cut will produce a result of the form "123 4", > causing the evaluation > of TIME to fail. Thanks, I fixed this now in my bzr tree and it will be part of the next upload. Cheers, Michael -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Bug#695285: /etc/cron.daily/apt backup RNG is very wasteful
Package: apt Version: 0.9.7.6 Severity: minor /etc/cron.daily/apt does: random_sleep() { RandomSleep=1800 eval $(apt-config shell RandomSleep APT::Periodic::RandomSleep) if [ $RandomSleep -eq 0 ]; then return fi if [ -z "$RANDOM" ] ; then # A fix for shells that do not have this bash feature. RANDOM=$(dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -c"1-5") fi TIME=$(($RANDOM % $RandomSleep)) debug_echo "sleeping for $TIME seconds" sleep $TIME } This backup for a missing $RANDOM reads 512 bytes out of /dev/urandom, only to reduce it (incorrectly) to a 5-digit number (16.6 bits max, although the distribution is skewed), then to 10.8 bits (modulo 1800). It's incorrect because cksum produces a 32-bit checksum, formatted as "%u", so some small fraction of the time (1 in 4.3 million times), it'll be less than 1000 and the cut will produce a result of the form "123 4", causing the evaluation of TIME to fail. Two other options, which both use a lot less entropy and don't have the bug, are: RANDOM=$(dd if=/dev/urandom bs=2 count=1 2>/dev/null | cksum | cut -d' ' -f1) RANDOM=$(od -N2 -d /dev/urandom | cut -s -d' ' -f2) or, using more shell builtins: read x RANDOM <