4
dd if=/dev/urandom of=a.log bs=1M count=2

Question: if this code ^ gives me random numbers, how can I get random non-words (unintelligible) such as “hgcqw”.

Question 2: Can the shuf command be used in conjunction with the dd command?

Thanks!

6/21 Update. (Father's day)

@ Serg My goal was to obtain numbers at first. Say, random two digits numbers from 01-100. Give the command and run the code. Eventually it will give me 14, 17, 21, 35 ( I am making up what random numbers I get). Next, I wanted to get an average of those numbers. In this case the average would be 21.75 (22). The goal would be to stop the loop until it finds a specific average I was looking for. In this case it would be 25. My second goal was to get random words and then get a count of what words were used.

@ terdon

A word is "buck", "duck," or "good old luck." Basically anything found in the dictionary. The lengths would be any yet if we were to constrain the limit to 5 letters, I wouldn't mind learning how?

What's a word? I presume you mean only a-z and A-Z but what lengths? Would liwyduglashvdbalishfvgapivflakhf be a word? How about ksjdas-asd-asd-asd? - can be in words. Please edit and clarify. – terdon yesterday

4
  • 3
    What's your goal ? Jun 19, 2015 at 16:33
  • 4
    What's a word? I presume you mean only a-z and A-Z but what lengths? Would liwyduglashvdbalishfvgapivflakhf be a word? How about ksjdas-asd-asd-asd? - can be in words. Please edit and clarify.
    – terdon
    Jun 19, 2015 at 17:19
  • @ Serg My goal was to obtain numbers at first. Say, random two digits numbers from 01-100. Give the command and run the code. Eventually it will give me 14, 17, 21, 35 ( I am making up what random numbers I get). Next, I wanted to get an average of those numbers. In this case the average would be 21.75 (22). The goal would be to stop the loop until it finds a specific average I was looking for. In this case it would be 25. My second goal was to get random words and then get a count of what words were used.
    – ricomon
    Jun 21, 2015 at 14:56
  • @ricomon: Thanks for adding more detail to your question. Unfortunately it's still unclear. Please give a precise description of the expected output with one ore more examples! On top of that, I feel, that it's becoming more a question about programming than about Bash, so you may get better answers on Stack Overflow, but in the current state they will likely close your question for the same reason: lack of clarity. Jun 21, 2015 at 15:39

6 Answers 6

8

Generate a random alphabetic character.

tr -cd '[:alpha:]' < /dev/urandom | fold -w1 | head -n1  

Generate a random alphabetic string 10 characters in length.

tr -cd '[:alpha:]' < /dev/urandom | fold -w10 | head -n1

Some of the alternative POSIX character classes to use instead of the alpha in [:alpha:] are: alnum - alphanumeric characters
alpha - alphabetic characters
digit - digits
graph - visible characters
lower - lowercase characters
upper - uppercase characters

Generate random numbers in a specific range (example 1-10).

shuf -i 1-10 -n1  

Compared to the first two bash examples, the shuf command offers fewer options for generating random strings , although shuf can be used to generate random permutations.

1
  • 1
    With GNU coreutils, "fold -w$N | head -n1" can be simplified to "head -c$N".
    – David
    Jun 19, 2015 at 17:40
7
dd if=/dev/urandom of=a.log bs=1M count=2

This doesn't give you random numbers. This gives you random bytes. You could encode it to numbers:

hexdump -v -e '"%d\n"' /dev/urandom | dd of=a.log bs=1M count=2

(The earlier version used od, but od's output format is rather inflexible.)

Using /dev/random directly might be rather wasteful, since it is a stream of bytes. You could encode it to base64, and then strip out non-alphabets, which should still get you, on an average, 80 % of the input data:

base64 /dev/urandom | tr -cd '[[:alpha:][:space:]]'

This tends to leave rather long lines. You could, instead, replace numbers with newlines:

base64 /dev/urandom | sed 's/[^[:alpha:]]\+/\n/g'
9
  • 1
    This is way faster than my version, however have you checked the output? It doesn't contain spaces, and it's randomly splitted into lines.
    – kos
    Jun 19, 2015 at 17:08
  • @kos of base64?
    – muru
    Jun 19, 2015 at 17:11
  • Yes, it prints lines of a lenght about the width of the terminal not containing spaces
    – kos
    Jun 19, 2015 at 17:16
  • @kos base64 dumps lines of 80 characters, no spaces (deleting digits leaves shorter lines). You'll have to use fold or something to get even splitting.
    – muru
    Jun 19, 2015 at 17:18
  • 1
    @kos how about base64 /dev/urandom | sed 's/[^[:alpha:]]/ /g'?
    – muru
    Jun 19, 2015 at 17:30
4

To generate a random alphabetic lower-case string (including spaces) of 2MB:

< /dev/urandom tr -dc 'a-z ' | head -c 2000000 > a.log

For a constant stream:

< /dev/urandom tr -dc 'a-z '

To generate a random alphabetic mixed-case string (including spaces) of 2MB:

< /dev/urandom tr -dc 'A-Za-z ' | head -c 2000000 > a.log

For a constant stream:

< /dev/urandom tr -dc 'A-Za-z '
4
  • Works, but needs a | head -c # at the end so that it gives a word at # number of characters long
    – Terrance
    Jun 19, 2015 at 16:36
  • @Terrance There you go
    – kos
    Jun 19, 2015 at 16:38
  • You got my +1. :) Works great!
    – Terrance
    Jun 19, 2015 at 16:42
  • Similar Ruby solution: ruby -e '100.times do print [*?a..?z," "].sample; end'
    – Doorknob
    Jun 20, 2015 at 6:09
3

An other version (-c${1:-10} = length of 10):

< /dev/urandom tr -dc A-Za-z | head -c${1:-10} > out

or (head -n 10 = length of 10)

strings /dev/urandom | grep -o '[[:alpha:]]' | head -n 10 | tr -d '\n' > out

or with dd (count=10 = length of 10)

dd if=/dev/urandom bs=1 count=10 2>/dev/null | base64 | grep -o '[[:alpha:]]' | head -n 30 | tr -d '\n' > out

or this

openssl rand -base64 32| grep -o '[[:alpha:]]' | head -n 10 | tr -d '\n' > out

or this

date +%s | sha256sum | base64 | grep -o '[[:alpha:]]'| head -n 10 | tr -d '\n' > out
3

Here's my idea. mkpasswd is used often to generate encrypted passwords, hence the strings there shouldn't be intelligible already. The small problem is that it generates strings with numbers. By using sed, we can get rid of those.

mkpasswd | sed 's/[0-9]/YOLO/g'

YOLO could be whatever you want to substitute digits. You could also just delete them:

mkpasswd | sed 's/[0-9]//g'

Here's another way:

$ date | md5pass | sed 's/[0-9]//g'                                                                                                   
$$NG.dLw$vcpGCylnDtmptDtogDr/

As muru suggested in the comments bellow , you can also install pwgen, with sudo apt-get install pwgen, and run pwgen -0. The -0 flag tells the command to avoid numerals

And here's sha1pass + sed combo:

sha1pass | sed 's/[[:digit:]]//g' | sed 's/[[:punct:]]//g'
Result: PoXGAlAWjzMHgmfzHiYHGpemzqE

Another method with $RANDOM variable: echo $RANDOM | tr '0-9' 'a-z'

Overall, if your goal is password generation, I suggest you read this article:

http://www.howtogeek.com/howto/30184/10-ways-to-generate-a-random-password-from-the-command-line/

4
  • pwgen! pwgen -0 does this.
    – muru
    Jun 19, 2015 at 17:08
  • @muru yup, good one, but requires installation Jun 19, 2015 at 17:10
  • Note tr is specially for this, no need to sed: tr -d '[[:digit:]], etc.
    – fedorqui
    Jun 19, 2015 at 19:39
  • I was not looking for a password generator approach but thanks so much for the info @ Serg. I did think about how this was done. @ Serg.
    – ricomon
    Jun 21, 2015 at 15:00
3

Using python:

#!/usr/bin/env python2
import random, string 
def rand_gen(number_of_words, length):
    for i in range(number_of_words):
        print ''.join(random.choice(string.ascii_lowercase + string.ascii_uppercase) for _ in range(length))
    return
  • We have defined a function rand_gen(number_of_words, length) that will take two parameters as inputs, number_of_words will contain the number of random words you want to generate, length will contain the length of each random word

  • string.ascii_lowercase and string.ascii_uppercase have all the ASCII lowercase and uppercse letters respectively

  • random.choice will choose a single character from [A-Za-z] each time and length will ensure that this iteration continues upto the length number. join() will then join the characters to have a word of desired length

  • This process will be continued till number_of_words

Example :

rand_gen(5, 3)
PDI
qKQ
Dvu
kwr
wDz

rand_gen(2, 5)
GLKXr
uOaHj

Not the answer you're looking for? Browse other questions tagged .