This was tested on macOS (instead of AIX), but it should work on AIX as well:
#!/bin/ksh
LC_ALL=C tr -dc '[:alnum:]' < /dev/urandom | dd cbs=60 conv=unblock | awk '
{ #print "Input line read:", $0
for(i = 1; i <= length($0); i++)
a = (substr($0, i, 1) ~ /[[:alpha:]]/)
for(i = 1; i <= length($0) - 7; i++) {
if((n = (a + a[i+1] + a[i+2] + a[i+3] + \
a[i+4] + a[i+5] + a[i+6] + a[i+7])) == 6) {
printf("Found password \"%s\"\n", substr($0, i, 8))
exit
}#else printf("Tried \"%s\" %d alpha, %d num\n",
# substr($0, i, 8), n, 8 - n)
}
}'
If you remove the # characters from the above script, it will show you the input it got from /dev/urandom and the possible passwords it tested from that input before reaching a password that meets your criteria.
Note that the dd in the pipeline is because standard implementations of awk are defined to work on text files while the output from the tr command is a single incomplete line of infinite length (while a text file is limited to lines containing no more than LINE_MAX bytes (where LINE_MAX is 2048 bytes on most UNIX systems)). Having dd produce lines of 61 characters per line (counting the terminating <newline> character) was a choice to make the debugging output easy to read in an 80 column window. If you don't care about the debugging output, you might want to increase the line size slightly. Note, however, that even with a line length of just 60 characters, I only saw this script read a second line of input once in 50 tests with debugging output enabled. Furthermore, if you are using an awk that can handle "unlimited" line lengths, the algorithm used in this script will not make any attempt to look for a password until a complete line has been read.
Hi Scrutinizer,
I like your code better than mine. But if my dd was terminating on a SIGPIPE signal and generating an unwanted diagnostic for infernalhell, I don't see why the fold in your pipeline wouldn't suffer from the same fate.
Given that PIPE_BUF has a minimum allowed size of 512 bytes, using the following:
dd cbs=1 conv=unblock ibs=256 count=1
instead of:
fold -w1
might avoid the diagnostic message. But, of course, if 2 numeric characters and 6 alphabetic characters aren't found in the first 256 alphanumeric characters found in the data in /dev/random you won't get any output from your script. I would expect the likelihood of that happening being less than 3%.