-
Notifications
You must be signed in to change notification settings - Fork 0
/
ran
executable file
·96 lines (88 loc) · 2.45 KB
/
ran
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/bin/sh
mseed() {
[ -c /dev/urandom -a ! "$PID" ] && {
read -r seed < /dev/urandom # read a single line of urandom
seed=${#seed}
} || { # otherwise generate a seed using pids
# $PID may be set to force usage of pids
echo '!!USING PIDS!!' >&2
: & wait; o="$!"; for i in 1 2 3 4 5; do
: & wait # generate new $!
o=$((o%o+$!*o))
done
for i in 1 2 3; do
: & wait
done
seed="$((o%o+$!*${#o}))" # greatly shorten seed
# large seeds produce large numbers = more randomness
}
# L105
[ -c /dev/urandom ] && {
read -r o < /dev/urandom
o="${#o}"
} || {
# warn about lack of hardware randomness
: & wait
o="$!" # pid is "RANDOM"
for i in 1 2 3; do
: & wait
done # 3 pid calls
o="$((o%o*o+$!))" # this allows the last digit to actually be random
}
: $((seed+=o))
# use $o to add possibility of odd number
printf '%s\n' "$seed"
}
# make seed ^
sadd() {
str="$1"
while [ "$str" ]; do
next="${str#?}"; current="${str%$next}"
out=$(($(printf "%d" "\"$current")+${out:-0}))
str="$next"
done
printf '%s\n' "$out"
unset out str next
}
unset s0 s1 seed
[ "$1" ] || set -- "$(mseed)" "$(mseed)" "uran"
[ "$1" -a ! "$2" ] && set -- $1 0
# first check if $2 is unset
## if $2 is unset, $3 will also be unset
if [ ! "$PID" ] && [ "$3" != "uran" ]; then
PID="$3"
fi
# PID vs uran actually has no effect if a seed is given
[ "$1" = "-" -a "$2" = "-" -a "$3" ] && {
[ "$3" != "uran" ] && PID="$3"
set -- "$(mseed)" "$(mseed)" "$3"
}
[ "$1" -eq "$1" ] 2>/dev/null || {
set -- $(sadd "$1") "$2" "$3"
}
[ "$2" -eq "$2" ] 2>/dev/null || {
set -- "$1" "$(sadd $2)" "$3"
}
# sadd should add together all the ascii values of $1
set -- ${1:-$(mseed)} ${2:-$(mseed)}
# then mseed takes over
s0="$1"; s1="$2"
# if no second seed is given, default to 0
# otherwise the output will differ for each seed
##
# the better idea is to take $1 and split it
# however this requires the $1 be at least 2char in size
# an attempt at xoroshiro64** follows
# this is based off the reference code @ https://prng.di.unimi.it/xoroshiro64starstar.c
# keep in mind I have no idea how most of this works
rotl() {
echo $(( ($1 << $2) | ( $1 >> (32 - $2) ) ))
} # return (x << k) | (x >> (32 - k))
next() {
# s0/s1 are generated above @ L42-49
: $((s1 ^= s0))
s0=$(($(rotl s0 26) ^ s1 ^ (s1 << 9)))
s1=$(rotl $s1 13)
echo $(($(rotl $((s0*0x9E3779BB)) 5)*5)) # result
}
o=$(next); echo 0.${o#-}