unix - What's the best way to get a random(ish) sequence of printable/alphanumeric characters?
2014-04
I know I can get random (well, pseudo-random) characters, unconstrained, from '/dev/random'
(or /dev/urandom
). But what if I need these characters to generate a filename? I need to somehow have a stream or a sequence of printable characters, or alphanumeric ones to be on the safe side. What's the best way to do that in the shell?
(I know I could theoretically do a tr
on chars from /dev/random
but that doesn't sound like the right thing to do.)
I see /usr/bin/jot
is capable of suppling a specified count of constrained random characters, which can be reshaped to a word suitable for a filename. There's probably a more eloquent way of specifying all printable characters, but I'm a bit rusty on my shell scripting.
[mini-nevie:~] nevinwilliams% jot -r -c 25 A Z | rs -g
EUCGGSIOIDMPCHXCHIGYXBYWJ
[mini-nevie:~] nevinwilliams% jot -r -c 25 A Z | rs -g
PMKQQZOCYETVIHIMTIQFYTFZK
[mini-nevie:~] nevinwilliams% jot -r -c 25 A Z | rs -g
CXBKEFSIRCOOGUICJPOMZKMSG
[mini-nevie:~] nevinwilliams% jot -r -c 25 A Z | rs -g
MEHSFOSHLKKJRKQLRCXUCBJAD
[mini-nevie:~] nevinwilliams% jot -r -c 25 A Z | rs -g
ZCCGKYIWLBTJUVIHQBCHXCVEU
$ dd if=/dev/urandom of=/dev/stdout bs=124 count=1 2>/dev/null | sha256sum | awk '{print $1}'
A tweaking of @dawud's solution:
dd if=/dev/urandom bs=124 count=1 2>/dev/null | sha256sum | cut -c1-64
gets you 64 characters; and you can use /dev/random
on UN*X systems without /dev/urandom
.
A different, simpler approach, based on @NevinWilliam's suggestion: just do
date +%s.%N
No alphabet characters is a special case of alphanumeric... this doesn't cover the whole range of possible strings, and is limited to 9 characters, and it's not very random - except maybe the last 2-4 digits or so - but since we're not doing crypto, this should be good enough.
I found this command here.
The command is structured as a registry modification that will add a "Take Ownership" entry in the standard Windows Explorer file/directory context menu. I can see where it uses cmd.exe, and I can sort of understand what's happening from there.
The registry modification contains several commands, but I'm specifically interested in the command to take ownership and grant permissions on a directory tree:
[HKEY_CLASSES_ROOT\Directory\shell\runas]
@="Grant Admin Full Control"
"NoWorkingDirectory"=""
[HKEY_CLASSES_ROOT\Directory\shell\runas\command]
@="cmd.exe /c takeown /f \"%1\" /r /d y && icacls \"%1\" /grant administrators:F /t"
"IsolatedCommand"="cmd.exe /c takeown /f \"%1\" /r /d y && icacls \"%1\" /grant administrators:F /t"
One of the problems is that - because of the way the command is executed - it explicitly invokes cmd.exe with the /C switch. This causes escape sequences to be required for quotation marks (which I don't entirely understand). The command also contains tokens that I have no idea how to use from the command-line ("takeown", "icacls", etc). On top of that, the command is split onto two separate lines, with a line-break in between - which I assume would cause cmd.exe to attempt to execute it as two separate commands, when it does not appear to be such.
I need to convert command into a script file (one that doesn't open another instance of cmd.exe - presumably a batch), with an explicit directory replacing the "%1". The only restriction at this point is that this script needs to be able to run as a shutdown script in the local Group Policy. I don't trust myself to do it correctly, since I have little understanding of the syntax used in this registry modification. As such, it's pretty risky for me to try to do it myself. Who knows what damage I could cause if I got the syntax wrong.
Therefore I'm asking if anyone can point me in the right direction - bonus points for explicit examples.
takown and isacls are DOS commands. As there is no path specified to reach them in the Registry file, I assume they are available on the path.
Just create a batch file (say ownandgrant.bat) containing
@echo off
takeown /f %1 /r /d y
icacls %1 /grant administrators:F /t
This could cause issues if the directory name contains 1 or more spaces so make sure you enclose the directory with double quotes when calling the batch file.
ownandgrant.bat "my special directory"