Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

I would like to generate a random string (e.g. passwords, user names, etc.). It should be possible to specify the needed length (e.g. 13 chars).

What tools can I use?

share|improve this question
    
There are already good answers are at AskUbuntu. (I use apg personally.) –  Sparhawk 21 hours ago
    
@Sparhawk The AskUbuntu question/answers are more about listing tools. Please consider adding an answer here exhibiting how to use apg to generate a random string. –  landroni 18 hours ago

6 Answers 6

To generate a random password you can use pwgen:

pwgen generates random, meaningless but pronounceable passwords. These passwords contain either only lowercase letters, or upper and lower case mixed, or digits thrown in. Uppercase letters and digits are placed in a way that eases remembering their position when memorizing only the word.

Generate 7 passwords of length 13:

geek@liv-inspiron:~$ pwgen 13 7
Eu7Teadiphaec giepahl3Oyaiy iecoo9Aetaib4 phaiChae6Eivi athoo3igee8Co
Iphu4ufeDeelo aesoYi2lie9he 

As mentioned in the comments, you can avoid reducing entropy by using the -s argument (i.e. generate more secure, completely random but hard to remember passwords):

geek@liv-inspiron:~$ pwgen -s 13 7
eAfycrPlM4cYv 4MRXmZmyIVNBp D8y71iqjG7Zq7 FQRHcserl4R8O yRCUtPtV3dsqV
0vJpp2h0OrgF1 QTp7MKtJyTrjz 

To generate random user names you can use gpw:

This package generates pronounceable passwords. It uses the statistics of three-letter combinations (trigraphs) taken from whatever dictionaries you feed it.

Generate 7 passwords (user names) of length 13:

geek@liv-inspiron:~$ gpw 7 13
sreepoidahsas
risadiestinge
ntodynesssine
deodstestress
natinglumperm
riasigentspir
enderiferback
share|improve this answer
4  
+1 for not reinventing the wheel. If you don't want the reduced entropy of the "pronounceable" constraint, simply use pwgen -s. –  Nate Eldredge yesterday

My favorite way to do it is by using /dev/urandom together with tr to delete unwanted characters for instance to get only numbers and letters:

head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13
share|improve this answer
7  
Or do this: head /dev/urandom | tr -dc A-Za-z0-9 | head -c10 - This way is more accurate. You get 10 characters that are capitals, lowers, or digits –  Brandin 2 days ago
1  
@landroni To add the \n in the output you'll probably have to add it yourself. Here's a simple bash syntax shell function - make it a shell script if you want: function genPass() { N=${1:-8}; head /dev/urandom | tr -dc A-Za-z0-9 | head -c$N; echo ""; } –  Brandin 2 days ago
1  
@landroni Or if you want an easier one-liner, use echo with backticks to generate the \n for you: echo "$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c10)" –  Brandin 2 days ago
4  
The first head command might be problematic. It will output the first 10 lines from /dev/urandom, which means it will stop once it has seen the 10th newline. So the length of the output send to the tr command is random. It is possible that there will be less than 13 characters in the output from tr. I haven't computed the probability of this happening, the calculations are a bit tricky. –  kasperd yesterday
1  
Better do it like this: <dev/urandom tr -dc "$charset" | head -c "$length" –  PSkocik 21 hours ago

Here is how, I do it. It generates 10 characters random string. You can optimize it by replacing the "fold", with other string processing tools.

cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 10 | head -n 1
share|improve this answer
    
+1 I like this approach, thanks. Allows to control both length and number of generated strings. –  landroni yesterday

@Brandin explained in a comment to another answer how to get at most 100 bytes from /dev/urandom using head -c 100. Another way to do this is with dd:

tr -dc A-Za-z0-9 < /dev/urandom | dd bs=100 count=1 2>/dev/null

The 2>/dev/null at the end of the dd command is to suppress the "... records in / ... records out" output.

I'm not aware of any substantial advantages/disadvantages between these two methods.

I had an issue with both methods of tr complaining about the input. I thought this was because it didn't like receiving binary input, and hence suggested first filtering /dev/random with iconv -c -t US. However, Gilles suggested a different diagnosis and solution, which works for me:

LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | dd bs=100 count=1 2>/dev/null
share|improve this answer
    
For some reason the iconv solution maxes one CPU core and doesn't yield an output (I waited some 10s before killing it)... –  landroni 2 days ago
    
On my Ubuntu 14.04 system iconv is provided by libc-bin 2.19. I'm not sure if it's the same iconv... –  landroni yesterday
    
tr supports binary input. However a range like A-Z may be influenced by locale settings. Try LC_ALL=C tr … –  Gilles yesterday

Depending on the level of randomness you want, you could simply go with bash's (also zsh and ksh, possibly others) builtin $RANDOM variable:

$ echo $RANDOM | tr '[0-9]' '[a-zA-Z]'
bfeci
$ echo $RANDOM | tr '[0-9]' '[a-zA-Z]'
cijjj

The methods reading directly from /dev/urandom are far simpler, but for the sake of completion, you could also use $RANDOM:

echo $(for((i=1;i<=13;i++)); do printf '%s' "${RANDOM:0:1}"; done) | tr '[0-9]' '[a-zA-Z]'
share|improve this answer
    
How do you control the length of the generated string? –  landroni yesterday
    
@landroni I don't think you can short of using a loop until you get the right length. $RANDOM will print a number between 0 and 32767. –  terdon yesterday
    
I've tried running the command some 20 times, and I can never get anything longer than 4-5 chars... –  landroni yesterday
    
@landroni yes, that's what I said, it generates numbers between 0 and 32767, so 5 digits will be the max. If you need longer ones or need to be ab;e to specify the length, please edit your question and make that clear. –  terdon yesterday
1  
@landroni thanks, I've added a way to specify length but it's not very good. I'd just use something like rand=$(head -c 100 /dev/urandom | tr -dc A-Za-z0-9 | head -c13) instead. –  terdon yesterday

A super easy and simple (probably more simple than you're looking for) way to achieve this would be to generate a random number in a given range, convert that number to its equivalent ASCII character, and append it to the end of a string.

Here's a basic example in Python:

import random # import random library  
passFile = open("passwords.txt", 'w') # create file passwords.txt
passNum = int(input("Number of passwords: ")) # get number of  passwords
passLength = int(input("Password length: ")) # get length of passwords  
for i in range(passNum):
    password = "" # reset password
    for i in range(passLength):
        num = random.randint(65, 122) # get random number
        while num in range(91, 97): # Don't include punctuation
            num = random.randint(65, 122)
        password += chr(num) # add character to current password 
    passFile.write(password + "\n") # add current password to file  
passFile.close() # close file

EDIT: added comments, and added code to generate multiple passwords and write them to a file

share|improve this answer
2  
If given the power of Python I would NOT do it in this fashion. It would be much easier to use a join on a string containing all characters valid for a password and using random to select out the characters. –  Mike McMahon yesterday
    

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.