Skip to content

Instantly share code, notes, and snippets.

@JackZielke
Last active August 19, 2017 17:24
Show Gist options
  • Select an option

  • Save JackZielke/b0bd3b887820bef55c164e7cc9541f1d to your computer and use it in GitHub Desktop.

Select an option

Save JackZielke/b0bd3b887820bef55c164e7cc9541f1d to your computer and use it in GitHub Desktop.
Use random binary data to create various non-biased passwords
#!/bin/sh
# Source of random data
#DEV=/dev/urandom
#DEV=/dev/random
#DEV=/dev/hwrng
DEV=/var/run/rtl_entropy.fifo
# Remap unused characters
# OWASP will no longer look like alphanum
REMAP=1
OUT=
for cmd in bc head sed tail tr xxd; do
command -v $cmd >/dev/null || OUT="$OUT $cmd"
done
if test -n "$OUT"; then
echo "The following required command(s) are missing:$OUT"
exit 1
fi
if test $# -ne 0; then
if case $1 in (*[!0-9]*|"") false ;; (*) true ;; esac; then
LEN=$1
else
echo "$1 is not a number"
exit 1
fi
else
LEN=64
fi
H1=
H2=
C=1
S=0
while test $C -le $LEN; do
if test $((C%10)) -eq 0; then
H1="$H1$((C/10))"
S=$((${#C}-2))
else
if test $S -gt 0; then
S=$((S-1))
else
H1="$H1 "
fi
fi
H2="$H2${C#${C%?}}"
C=$((C+1))
done
A=
B=
C=
D=
E=
F=
if test $REMAP -eq 1; then
# 1.34738 from 1/(95/128)
MULT=14
MAP="tr '\200-\377' '\000-\177'|tr '\000-\031' 'A-Z'|tr '\032-\057' 'a-v'|tr '\072-\075' 'w-z'|tr '\133-\140' '0-5'|tr '\173-\176' '6-9'"
else
# 2.41510 from 1/(53/128)
MULT=25
MAP="tr '\200-\377' '\000-\177'"
fi
GET=$(($LEN*$MULT/10+1))
# Ensure base64 is not biased at the end
if test $MULT -lt 8; then
while test $((GET%3)) -ne 0; do
GET=$((GET+1))
done
fi
# B needs the most data w/out remap, C needs the most data with remap
while test ${#B} -lt $LEN -o ${#C} -lt $LEN; do
echo -n .
if test -z "$bin"; then
bin="$(head -c$GET <"$DEV"|xxd -p -u|tr -d '\n')"
else
bin="$(head -c15 <"$DEV"|xxd -p -u|tr -d '\n')"
fi
if test ${#A} -lt $LEN; then
A="$A$(echo -n $bin|xxd -r -p|eval $MAP|tr -dc A-Za-z0-9)"
fi
if test ${#B} -lt $LEN; then
B="$B$(echo -n $bin|xxd -r -p|eval $MAP|tr -dc A-Za-z0-9|tr -d O0Il12Z5S|tr -s vV)"
B="$(echo $B|tr -s vV)"
fi
if test ${#C} -lt $LEN; then
C="$C$(echo -n $bin|xxd -r -p|tr '\200-\377' '\000-\177'|tr -dc 'A-Za-z0-9 !"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~')"
C="$(echo $C|sed 's/\(.\)\1\1*/\1\1/g')"
fi
if test ${#D} -le $LEN; then
OUT=
MAX="$(echo "256^(${#bin}/2)-1"|BC_LINE_LENGTH=0 bc)"
DEC="$(echo "ibase=16;obase=A;$bin"|BC_LINE_LENGTH=0 bc)"
BUF=$(printf %0${#MAX}s|tr ' ' 0)
T=1
while [ $T -lt ${#MAX} ]; do
PRE=$(echo $MAX|head -c$T)
DIV=$(printf '%s%*.*s' $PRE 0 $((${#MAX}-$T)) $BUF)
if test $(echo $DIV-$DEC|BC_LINE_LENGTH=0 bc|head -c1) != '-'; then
M=$((${#MAX}-$T))
DEC=$(echo -n $DEC|tail -c$M)
# pad with zeros
while test ${#DEC} -lt $M; do
DEC="0$DEC"
done
OUT=$DEC
break
fi
T=$((T+1))
done
D="$D$OUT"
fi
if test ${#E} -le $LEN; then
E="$E$bin"
fi
if test ${#F} -le $LEN; then
F="$F$(echo -n $bin|xxd -r -p|base64 -w0)"
fi
done
echo
echo " $H1"
echo " $H2"
echo -n 'alphanum '
echo "$A"|head -c"$LEN";echo
echo -n 'visual C&P '
echo "$B"|head -c"$LEN";echo
echo -n 'OWASP '
echo "$C"|head -c"$LEN";echo
echo -n 'digits '
echo "$D"|head -c"$LEN";echo
echo -n 'raw hex '
echo "$E"|head -c"$LEN";echo
echo -n 'base64 '
echo "$F"|head -c"$LEN";echo
@JackZielke
Copy link
Author

Accepts password length as the 1 parameter, defaults to 64 characters. The guide helps with copying a portion of the output.

.
                    1         2         3         4         5         6    
           1234567890123456789012345678901234567890123456789012345678901234
alphanum   2w5U5eWM5rilPwN4kUvrn6MBqCaNG3JHnjPnFBwKGFkuv03NNBO7vutiesu0fx2J
visual C&P wUeWMriPwN4kUvrn6MBqCaNG3JHnjPnFBwKGFkuv3NNB7vutiesufxJWvECg4WBD
OWASP      ]?w5U`5r"%wN4$U/+n6MqCN^JH'jn:KGF$uv[3NB7vuti,u[f;]1/EC 4>B$vSGB
digits     0090746214674747111964328204908122411046269266795609811891640924
raw hex    5D3F77B5D5609E168C3572A2A50FF7CEB4A455AF2BEEB64D0171C39ACE865E4A
base64     XT93tdVgnhaMNXKipQ/3zrSkVa8r7rZNAXHDms6GXkrIp+qP7gWBOktHRiR19lsz

alphanum - Uppercase letters, lowercase letters, and numbers.
visual C&P - alphanum with the following characters removed: O0Il12Z5S, consecutive v and V (vv and VV).
OWASP - alphanum plus 33 characters suggested by OWASP.
digits - Digits from the raw binary read as a number and stripping the leading digits as necessary.
raw hex - Raw input converted to hexadecimal.
base64 - Raw input converted to base64.

alphanum, visual C&P, and OWASP have the high bit dropped (128-255 are remapped to 0-127).
alphanum and visual C&P optionally have unused characters remapped without introducing bias.
digits, raw hex, and base64 use the raw input.

The script is called staticpass because I am using radio static as my random data source via rtl-entropy. The script is somewhat painfully written for dash in the hopes that it will be more portable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment