unix - What's the best way to get a random(ish) sequence of printable/alphanumeric characters?

06
2014-04
  • einpoklum

    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.)

  • Answers
  • Nevin Williams

    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
    
  • dawud

    $ dd if=/dev/urandom of=/dev/stdout bs=124 count=1 2>/dev/null | sha256sum | awk '{print $1}'

  • einpoklum

    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.


  • Related Question

    shell - What's the best way to convert this complex "takeown" command into a shutdown script?
  • Giffyguy

    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.


  • Related Answers
  • Snark

    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"