Last active
December 25, 2015 15:59
-
-
Save rsvp/7002774 to your computer and use it in GitHub Desktop.
randout.sh :: readable random output from system kernel using /dev/urandom.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# bash 4.2.24(1) Linux Ubuntu 12.04 Date : 2013-10-19 | |
# | |
# _______________| randout : readable random output from system kernel. | |
# | |
# Usage: randout [bytes=512] [--TYPE] [characters/line] | |
# Types: space, graph, mime, url, alpha, alnum, alnoo, | |
# lonum, hex, digit (see case below for details). | |
# | |
# Examples: # Default type is --digit (but --hex is also available): | |
# $ randout 7 | |
# 9636770 | |
# | |
# # Types are generally named classes, however, e.g.: | |
# $ randout 10 --lonum | |
# 91wkkxf838 | |
# | |
# # Third arg sets chars/line; otherwise all on one line: | |
# $ randout 35 --graph 10 | |
# J6zk+2X]6_ | |
# ^f%jY!l;:' | |
# BV2;SLIGt| | |
# +./9e | |
# | |
# | |
# Dependencies: /dev/urandom (non-blocking, unlike /dev/random) | |
# sed (version which accepts \n on RHS of substitution) | |
# CHANGE LOG LATEST version available: https://bitbucket.org/rsvp/gists/src | |
# | |
# 2013-10-19 Add url type, Base64 safe for URL and filename per RFC 4648. | |
# Re Base64: http://en.wikipedia.org/wiki/Base64 | |
# 2013-10-18 Add alnoo type = alnum without O or o letters. | |
# Fix range to A-Z where necessary. Eliminate cat pipe; faster. | |
# 2013-10-11 Fix sed for one EOL per non-empty line. Add mime type. | |
# 2013-10-10 First version; for exposition, see | |
# https://source.quora.com/Source-of-randomness-in-Linux-and-the-U-S-NIST | |
# Wrote this because U.S. NIST Beacon was part of gov shutdown. | |
# _____ PREAMBLE_v2: settings, variables, and error handling. | |
# | |
LC_ALL=POSIX | |
# locale means "ASCII, US English, no special rules, | |
# output per ISO and RFC standards." | |
# Esp. use ASCII encoding for glob and sorting characters. | |
shopt -s extglob | |
# ^set extended glob for pattern matching. | |
shopt -s failglob | |
# ^failed pattern matching signals error. | |
set -e | |
# ^errors checked: immediate exit if a command has non-zero status. | |
set -u | |
# ^unassigned variables shall be errors. | |
# Example of default VARIABLE ASSIGNMENT: arg1=${1:-'foo'} | |
arg1=${1:-'64'} | |
# ^number of output bytes. | |
arg2=${2:-'--digit'} | |
# ^type of string | |
arg3=${3:-$arg1} | |
# ^characters per line (PGP uses 64). | |
program=${0##*/} # similar to using basename | |
memf=$( mktemp /dev/shm/88_${program}_tmp.XXXXXXXXXX ) | |
cleanup () { | |
# Delete temporary files, then optionally exit given status. | |
local status=${1:-'0'} | |
rm -f $memf | |
[ $status = '-1' ] || exit $status # thus -1 prevents exit. | |
} #-------------------------------------------------------------------- | |
warn () { | |
# Message with basename to stderr. Usage: warn "message" | |
echo -e "\n !! ${program}: $1 " >&2 | |
} #-------------------------------------------------------------------- | |
die () { | |
# Exit with status of most recent command or custom status, after | |
# cleanup and warn. Usage: command || die "message" [status] | |
local status=${2:-"$?"} | |
cleanup -1 && warn "$1" && exit $status | |
} #-------------------------------------------------------------------- | |
trap "die 'SIG disruption, but cleanup finished.' 114" 1 2 3 15 | |
# Cleanup after INTERRUPT: 1=SIGHUP, 2=SIGINT, 3=SIGQUIT, 15=SIGTERM | |
# | |
# _______________ :: BEGIN Script :::::::::::::::::::::::::::::::::::::::: | |
# # 2013-10-10 My one-liner for digit case explained. Case added later. | |
# | |
# cat /dev/urandom | strings --all | sed -e 's/[^0-9]//g' | tr -d '\n' \ | |
# | head --bytes=$arg1 | |
# | |
# # From /dev/urandom filter out everything except readable characters for sed | |
# # which will then accept only digits, but tr is needed to remove line returns. | |
# # Finally use head to limit the stream output to default 512 bytes. | |
# This whole paragraph is actually an ONE-LINER... | |
strings --all /dev/urandom \ | |
| case "$arg2" in | |
'--space') cat ;; | |
# ^Include space and TAB | |
'--graph') sed -e 's/[[:space:]]*//g' ;; | |
# ^Non-space characters | |
'--mime') sed -e 's/[^0-9A-Za-z+/]//g' ;; | |
# ^ALPHANUMERIC / + Base64 | |
# a.k.a. Radix-64 OpenPGP. | |
# Padding char = not added. | |
'--url') sed -e 's/[^-0-9A-Za-z_]//g' ;; | |
# ^ALPHANUMERIC - _ Base64 | |
# Filename safe RFC 4648. | |
'--alnum') sed -e 's/[^0-9A-Za-z]//g' ;; | |
# ^ALPHANUMERIC | |
'--alnoo') sed -e 's/[^0-9A-NP-Za-np-z]//g' ;; | |
# ^ALPHANUMERIC less O & o | |
# thus zero is distinctive. | |
'--alpha') sed -e 's/[^A-Za-z]//g' ;; | |
# ^ALPHA characters only | |
'--lonum') sed -e 's/[^0-9a-z]//g' ;; | |
# ^Lower case w/ numbers | |
'--hex') sed -e 's/[^0-9A-F]//g' ;; | |
# ^HEX | |
'--digit') sed -e 's/[^0-9]//g' ;; | |
# ^DIGITS only. | |
*) die "undefined arg: $arg2" 113 ;; | |
esac \ | |
| tr -d '\n' | head --bytes=$arg1 \ | |
| sed -e "s/.\{$arg3\}/&\n/g" -e 's/$/\n/' \ | |
| sed -e '/^$/d' | |
# First part of sed break up the stream into lines | |
# of fixed length given by arg3. The second part | |
# insures that the stream always ends with EOL. | |
# The final sed is needed to re-read the stream, | |
# then delete any blank lines for consistent output, | |
# i.e. a line always ends with EOL. | |
cleanup | |
# _______________ EOS :: END of Script :::::::::::::::::::::::::::::::::::::::: | |
# vim: set fileencoding=utf-8 ff=unix tw=78 ai syn=sh : |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment