summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKerin Millar <kfm@plushkava.net>2024-06-02 18:46:43 +0100
committerKerin Millar <kfm@plushkava.net>2024-06-12 08:06:41 +0100
commit5ee035a364bea8d12bc8abfe769014e230a212a6 (patch)
tree0d16021306fa59a378f27386ee31d813aaf6167f
parentAdd the warn() function (diff)
downloadgentoo-functions-5ee035a364bea8d12bc8abfe769014e230a212a6.tar.gz
gentoo-functions-5ee035a364bea8d12bc8abfe769014e230a212a6.tar.bz2
gentoo-functions-5ee035a364bea8d12bc8abfe769014e230a212a6.zip
Add the srandom() function
This is based on the behaviour of the special SRANDOM variable in bash. It should be noted that sh is capable of bitwise arithmetic. For instance, it is possible to clamp the number in such a way that it does not exceed the minimum possible value of RAND_MAX (32767). n=$(srandom) && : $(( n >>= 17 )) Signed-off-by: Kerin Millar <kfm@plushkava.net>
-rw-r--r--functions.sh27
-rwxr-xr-xtest-functions22
2 files changed, 49 insertions, 0 deletions
diff --git a/functions.sh b/functions.sh
index a97dde7..0c35b2d 100644
--- a/functions.sh
+++ b/functions.sh
@@ -12,6 +12,7 @@
# The following variables affect initialisation and/or function behaviour.
# BASH : whether bash-specific features may be employed
+# BASH_VERSINFO : whether bash-specific features may be employed
# BASHPID : potentially used by _update_columns() to detect subshells
# COLUMNS : potentially used by _update_columns() to get the column count
# EERROR_QUIET : whether error printing functions should be silenced
@@ -474,6 +475,32 @@ vewend()
}
#
+# Generates a random uint32 with the assistance of the kernel CSPRNG.
+#
+srandom()
+{
+ # shellcheck disable=3028
+ if [ "${BASH_VERSINFO:-0}" -ge 5 ]; then
+ srandom()
+ {
+ printf '%d\n' "${SRANDOM}"
+ }
+ elif [ -c /dev/urandom ]; then
+ srandom()
+ {
+ printf '%d\n' "0x$(
+ LC_ALL=C od -vAn -N4 -tx1 /dev/urandom | tr -d '[:space:]'
+ )"
+ }
+ else
+ warn "srandom: /dev/urandom doesn't exist as a character device"
+ return 1
+ fi
+
+ srandom
+}
+
+#
# Prints a diagnostic message prefixed with the basename of the running script.
#
warn()
diff --git a/test-functions b/test-functions
index 8ff6380..0c4a222 100755
--- a/test-functions
+++ b/test-functions
@@ -397,6 +397,27 @@ test_yesno() {
iterate_tests 3 "$@"
}
+test_srandom() {
+ set -- \
+ eq 0 \
+ eq 0 \
+ eq 0 \
+ eq 0 \
+ eq 0
+
+ row=0
+
+ callback() {
+ number=$(srandom)
+ test_description="srandom ($(( row += 1 ))/5: ${number:-blank})"
+ is_int "${number}" \
+ && test "${number}" -ge 0 \
+ && test "${number}" -le 4294967295
+ }
+
+ iterate_tests 2 "$@"
+}
+
iterate_tests() {
slice_width=$1
shift
@@ -457,6 +478,7 @@ test_is_visible || rc=1
test_yesno || rc=1
test_die || rc=1
test_edo || rc=1
+test_srandom || rc=1
cleanup_tmpdir