- The binary format command allows you to convert a number into a character (or more generally, a binary string). The advantage of this first method is that you can easily create strings with characters that can not be found directly on the keyboard.
- By selecting characters at random from a given string you can control both which characters you get in the output and their relative frequency (by duplicating characters that should appear more often).
#
# Proc to generate a string of (binary) characters
# Range defaults to 'A'-'z' (this includes several non-alphabetic
# characters)
#
binary scan A c A
binary scan z c z
proc randomDelimString [list length [list min $A] [list max $z]] {
set range [expr {$max-$min}]
set txt ""
for {set i 0} {$i < $length} {incr i} {
set ch [expr {$min+int(rand()*$range)}]
append txt [binary format c $ch]
}
return $txt
}
#
# Proc to generate a string of (given) characters
# Range defaults to "ABCDEF...wxyz'
#
proc randomRangeString {length {chars "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"}} {
set range [expr {[string length $chars]-1}]
set txt ""
for {set i 0} {$i < $length} {incr i} {
set pos [expr {int(rand()*$range)}]
append txt [string range $chars $pos $pos]
}
return $txt
}
puts [randomDelimString 30]
puts [randomRangeString 30]
puts [randomRangeString 30 "aaabcdeeeeee"]
#
# Time the performance
#
puts [time {set x [randomDelimString 100]} 10000]
puts [time {set x [randomRangeString 100]} 10000]
if { 0 } {
# Sample output (Pentium II, 350 MHz, running Windows 98, Tcl 8.3.4):
[lmZQAiB]Hb_hFpEw`LiEQSjOSsBfC
BnnWCymqGYaFyAKOAMPfmnYKRJTugu
abcbdeaeeadeeeceaebaaebeeeebee
3564 microseconds per iteration
2862 microseconds per iteration
}In the chatroom, RS came up with the following solution:
proc lpick L {lindex $L [expr {int(rand()*[llength $L])}]}
proc randomlyPicked { length {chars {C G T A}} } {
for {set i 0} {$i<$length} {incr i} {append res [lpick $chars]}
return $res
}
puts [randomlyPicked 30]Stu 2007-02-14 The CAS extension also provides random char/string commands.
The random page also has a random string generator.
Stu 2007-10-23 Random A-Za-z one-liner:
proc randAZazStr {len} { return [subst [string repeat {[format %c [expr {int(rand() * 26) + (rand() > .5 ? 97 : 65)}]]} $len]] }aspect 2014-12: this previously had int(rand() * 10) > 5, which is a long-winded and incorrect way to flip coins (it's true only 40% of the time). A caution to those careless with entropy!
