Password generator

From Rosetta Code
Password generator is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Create a password generation program which will generate passwords containing random ASCII characters from the following groups:

  • lower-case letters: a-z
  • upper-case letters: A-Z
  • digits: 0-9
  • other printable characters excluding white-space, backslash and grave: !"#$%&'()*+,-./:;<=>?@[]^_{|}~


The generated password(s) must include at least one lower-case letter, one upper-case letter and one character from digits and 'other'. The user must be able to specify the password length and the number of passwords to generate. The passwords should be displayed or written to a file, one per line.

The randomness should be from a system source or library. The program should implement a help option or button which should describe the program and options when invoked. You may also allow the user to specify a seed value, and give the option of excluding visually similar characters (for example: Il1, O0, 5S).

J

Implementation:

<lang J>thru=: <. + i.@(+*)@-~ chr=: a.&i.

lower=: 'a' thru&.chr 'z' upper=: 'A' thru&.chr 'Z' digit=: '0' thru&.chr '9' other=: ('!' thru&.chr '~')-.lower,upper,digit,'`\'

pwgen =:verb define"0 :: pwhelp

 sizes=. #/.~ (i.4),?(y-4)#4 NB. how many of each?
 NB. pick allocated characters from each group, then shuffle 
 (?~@# { ]) ;sizes (?@(##) { ])each lower;upper;digit;other
 pwgen x#y

)

pwhelp =:echo bind (noun define)

 [x] pwgen y - generates passwords of length y
 optional x says how many to generate (if you want more than 1)
 y must be at least 4 because 
 passwords must contain four different kinds of characters.

)</lang>

Example use (from J command line):

<lang J> pwgen'help'

 [x] pwgen y - generates passwords of length y
 optional x says how many to generate (if you want more than 1)
 y must be at least 4 because 
 passwords must contain four different kinds of characters.
  pwgen 10

oUVT[+l2pk

  5 pwgen 10

456u;mJ#{Y WT^bf2|50) r&fLIY0IvW 4UZQC5!y:8 I}G86(;1Ob</lang>

zkl

Put the fallowing code into a file (such as pwdg.zkl): <lang zkl>var pwdLen=10, pwds=1, xclude="";

argh:=Utils.Argh( L("+xclude","","Don't use these characters",fcn(arg){ xclude=arg }), L("+len","","Number of characters in password", fcn(arg){ pwdLen=arg.toInt() } ), L("+num","","Number of passwords to generate", fcn(arg){ pwds=arg.toInt() } ), ); try{ argh.parse(vm.arglist) }catch{ System.exit(1) }

g1,g2,g3:=["a".."z"].walk(), ["A".."Z"].walk(), ["0".."9"].walk(); g4:="!\"#$%&'()*+,-./:;<=>?@[]^_{|}~".split(""); all:=(g1.extend(g2,g3,g4).concat() - xclude).split("");

do(pwds){

  pwd:=(T(g1,g2,g3,g4).pump(String,"shuffle",T("get",0)) - xclude).split("");
  println(pwd.extend(all.shuffle()[0,pwdLen - pwd.len()]).shuffle().concat());

}</lang> This is a command line program so output can be redirected.

Output:
$ zkl pwdg.zkl -?
Unknown option: ?
Options:
  --len <arg>: Number of characters in password
  --num <arg>: Number of passwords to generate
  --xclude <arg>: Don't use these characters

$zkl pwdg.zkl --len 20 --xclude "012345678" --num 5
O?a~siD&lK&<vL]od$|(
yhHVH})#S'F@<~%,Tb-L
?pOq"fmHAPtxgWM$n~u9
h&"#!bZGCm)dXt]$*)/p
x]*x>qH/Wde;asRzhZ.)