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) } isd:='wrap(w){ w.pump(String) - xclude }; // iterator to String g1,g2,g3 := isd(["a".."z"]), isd(["A".."Z"]), isd(["0".."9"]); g4:="!\"#$%&'()*+,-./:;<=>?@[]^_{|}~" - xclude; all:=String(g1,g2,g3,g4); fcn rnd(s){ s[(0).random(s.len())] } // pick a random character from s // generate random characters of filler needed to complete password fill:=(pwdLen-4).pump.fp(String,rnd.fp(all)); // a deferred/pending calculation do(numPwds){ // Data is byte bucket (and editor). I can shuffle a Data but not a String. pwd:=T(g1,g2,g3,g4).pump(Data,rnd); // 1 from each of these into a Data pwd.extend(fill()).shuffle().text.println(); }