Forum Discussion
How random is rand()?
How random is the tcl rand function?
We're currently using it to generate a unique(ish) value for each request we process - using a code bloc like this
set rnum [format "%08X" [expr { int(1000000000 * rand() ) } ] ]
set cthash [format "%08X" [clock clicks -milliseconds] ]
set tracker "$cthash$rnum
The tracker value then get inserted into a database. We would like to be comfortable in making it the primary key of the table (ie. no duplicates).
Is there a cryptogrpahically safe equivalent of rand() available from with iRules?
If I don't seed rand in a RULE_INIT event, will it be reseeded each time it's called?
Alternatively, does anyone have a method to generate a unique request identifier?
Cheers,
Rob
- Robert_Sutcliff
Nimbostratus
A solution I've come up with is to use a STATS profile.set iruleversion [format "%04X" 1] set F5id "[format "%02X" 1]" STATS::incr Booking_stats request_count set rnum [format "%08X" [STATS::get Booking_stats request_count] ] set cthash [format "%08X" [clock seconds] ] set tracker "$F5id$iruleversion$cthash$rnum"
- hoolio
Cirrostratus
Hi Rob,
Here is a method we used for a customer to generate a unique ID per HTTP request:
when RULE_INIT { Initialize 10 variables to track the distribution of first digits for {set i 0} {$i < 10} {incr i} { set $i 0 } Loop through and generate X number of random numbers for {set i 0} {$i < 1000} {incr i} { Save a new random number set random_number [expr {rand()}] set random_number_float [format %0.10f $random_number] Log the random number, the formatted string and the first digit log local0. "$random_number, [format %010s [string range $random_number 2 12]],\ [string range [format %010s [string range $random_number 2 12]] 0 0], $random_number_float" incr [string range [format %010.f [string range $random_number_float 2 12]] end end] } log local0. "Summary: " for {set i 0} {$i < 10} {incr i} { log local0. "$i: [set $i]" } }
For a run of 100,000 iterations, the distribution is fairly even:
Rule : Summary:
Rule : 0: 10114
Rule : 1: 9981
Rule : 2: 9781
Rule : 3: 9980
Rule : 4: 10104
Rule : 5: 9993
Rule : 6: 10074
Rule : 7: 10067
Rule : 8: 10013
Rule : 9: 9893
I got the basics from this TCL wiki page (http://wiki.tcl.tk/17696). I didn't seed rand as there were a few people stating:
as specifying our own seed for every call to roll is more likely to reduce randomness than improve it, I've left it out altogether.
Aaron
- StephanManthey
Nacreous
For several purposes (i.e. creating safe passphrases, cookies etc.) I´m using the rand function of TCL quite often.
But for peace of mind I had to prove two aspects of the random numbers:
* Will the random numbers be evenly distributed or will they follow a bell-shaped curve?
* Will rand return numbers less than 1 typically?
Indeed I made a (very short) attempt to have a look at the source code and quickly decided to follow an empiric approach. Instead of opening a new post I will add my 2 cents to this old thread.
Here is the iRule code returning i.e. 10,000 random numbers over a range of 0-20 upon request. A table is used to count the hits for each number in range.
when HTTP_REQUEST { remove existing table table delete -subtable randomtest -all find x random values in range of 0-y set x 10000 set y 20 for {set i 0} {${i} < ${x}} {incr i} { table incr -subtable randomtest key[format %03d [expr {int(rand()*${y})}]] } build output and prove number of results set j 0 set page "" for {set i 0} {${i} <= ${y}} {incr i} { if { [table lookup -subtable randomtest key[format %03d ${i}]] ne "" } { incr j [table lookup -subtable randomtest key[format %03d ${i}]] } append page "key[format %03d $i]: [table lookup -subtable randomtest key[format %03d $i]]\r\n" } append page "calculations: $j\r\n" return results HTTP::respond 200 content ${page} Connection Close Content-Type "text/plain; charset=us-ascii" return }
The iRule will be bound to a virtual server having an http-profile.
Send a request via browser or cURL as shown below.
A table is used to count the hits for each number in range.
The result shows an even distribution.
The number 20 (representing a random value of 1) doesnt show up.
$ curl http://10.1.1.61/ key000: 537 key001: 557 key002: 464 key003: 518 key004: 487 key005: 482 key006: 482 key007: 520 key008: 502 key009: 502 key010: 516 key011: 479 key012: 525 key013: 470 key014: 554 key015: 439 key016: 471 key017: 477 key018: 541 key019: 477 key020: calculations: 10000
Thanks, Stephan
Hi Folks,
I'm using a combination of the TMM_ID and a Timestamp to create unique request IDs that will never colide.
set uniqueID [TMM::cmp_unit][clock clicks]
Cheers, Kai
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com