Password generator: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|REXX}}: added the REXX language.)
m (showed the special characters in a larger font to they can more easily be discerned.)
Line 8: Line 8:
* digits: 0-9
* digits: 0-9


* other printable characters excluding white-space, backslash and grave: !"#$%&'()*+,-./:;<=>?@[]^_{|}~
* other printable characters excluding white-space, backslash and grave: <big><big> !"#$%&'()*+,-./:;<=>?@[]^_{|}~ </big></big>





Revision as of 09:21, 25 April 2016

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>

REXX

This REXX code was written as generically and idiomatically as possible so that the   special characters   and  
the lowercase and uppercase alphabets may be extended with letters from other alphabets. <lang rexx>/*REXX program generates a random password according to the Rosetta Code task's rules.*/ @abcL= 'abcdefghijklmnopqrstuvwxyz'; @abcU=@abc /*define a lower & uppercase alphabet. */ upper @abcU; @digs= 0123456789 /*uppercase a value; define numerals. */ @spec= '!"#$%&()+,-./:;<=>?@[]^{|}~' || "'" /*define a bunch of special characters.*/ parse arg L N seed . /*obtain optional arguments from the CL*/ if L== | L=="," then L=8 /*Not specified? Then use the default.*/ if N== | N=="," then N=1 /* " " " " " " */ if datatype(seed,'W') then call random ,,seed /*the seed for repeatable RANDOM BIF #s*/ if \datatype(L, 'W') then call ser "password length, it isn't an integer: " L if L<4 then call ser "password length, it's too small: " L if L>80 then call ser "password length, it's too large: " L if \datatype(N, 'W') then call ser "number of passwords, it isn't an integer: " N if N<0 then call ser "number of passwords, it's too small: " N

   do g=1  for N                                /*generate  N  passwords (default is 1)*/
   $=letterL()||letterU()||numeral()||special() /*generate  4  random  PW constituents.*/
           do k=5  to  L;       z=random(1, 4)  /* [↓]  flush out PW with more parts.  */
           if z==1  then $=$ || letterL()       /*maybe append random lowercase letter.*/
           if z==2  then $=$ || letterU()       /*  "      "      "   uppercase    "   */
           if z==3  then $=$ || numeral()       /*  "      "      "       numeral      */
           if z==4  then $=$ || special()       /*  "      "      "   special character*/
           end   /*k*/                          /* [↓]  code below randomizes PW chars.*/
   t=length($)                                  /*the length of the password (in bytes)*/
           do L+L                               /*perform a random number of char swaps*/
           a=random(1,t);     x=substr($,a,1)   /*A: 1st char location;  X is the char.*/
           b=random(1,t);     y=substr($,b,1)   /*B: 2nd   "      "      Y  "  "    "  */
           $=overlay(x,$,b);  $=overlay(y,$,a)  /*(both statements) swap the two chars.*/
           end  /*swaps*/                       /* [↑]  perform extra swap to be sure. */
   say right(g,length(N))  'password is: ' $    /*display the  Nth  password to console*/
   end       /*g*/

exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ ser: say; say '***error*** invalid' arg(1); exit 13 /*display an error message*/ letterL: return substr(@abcL, random(1, length(@abcL)), 1) /*return random lowercase.*/ letterU: return substr(@abcU, random(1, length(@abcU)), 1) /* " " uppercase.*/ numeral: return substr(@digs, random(1, length(@digs)), 1) /* " " numeral. */ special: return substr(@spec, random(1, length(@spec)), 1) /* " " special char*/</lang> output   when using the inputs of:   10   20

 1 password is:  17=6@@&6@l
 2 password is:  [:Bc13B;@A
 3 password is:  za@.3AxAoC
 4 password is:  x}Az!aj{6@
 5 password is:  k378BC,7w,
 6 password is:  v@<$B82C:0
 7 password is:  8aj4$+[+0@
 8 password is:  u:{ut7@{@C
 9 password is:  dA$)2l@+5C
10 password is:  ^A>|Cbc9gC
11 password is:  "@j0=C@#9<
12 password is:  w:AB8BCw99
13 password is:  tAu)7vrc0|
14 password is:  494b2o<B&A
15 password is:  18A92A84t(
16 password is:  B?eb82B:?3
17 password is:  @A+5ohB]CB
18 password is:  @nAt@^e['2
19 password is:  AaBB522/@w
20 password is:  yv8CB9A#[2

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