( mkpass 3/5/01 22:13 EPZ )

"rnd"
"tools"

\ service variable 
variable counter	counter off

\ current password length
\ default equals 8 symbols 
8 value pass-size

\ set of password's symbols
\ this is an array of CHARS
\ so we'll use operations C@ and
\ C!
62 CArray ChSet \ letters + digits

\ maximum length of password
16 constant MaxLength

\ array, representing password
\ this is an array of CHARS
\ we are using facts that array of
\ chars is a chain of bytes, so 
\ array of chars is the Forth string
\ without length byte on position 0
\ we can type array of chars,
\ knowing only its length
\ something like: pass pass-size type 
MaxLength CArray pass

\ filling array we will take symbols 
\ for password from
: fill-chset 26 0 Do 
i [char] A + i chset C! \ capital letters
i [char] a + i 26 + chset C! loop
\ small letters and digits 
10 0 do I  [char] 0 + i 52 + chset C! Loop ;

: ?not-end ( -- bool ) 
\ check if not end of string?
\ we analizing counter variable
counter @ pass-size 1-  - 0> not ; 

\ symbol on  (#counter) position
\  is unique?
: ?unique ( n -- bool )
	dup >upper
counter @ pass C@ <>
	swap >lower
counter @ pass C@ <> AND
;

: ?good ( u -- bool )
\ checking if U is unique in whole 
\ password
counter off 
begin
      Dup
     ?unique ?not-end AND
while  1 counter +! repeat drop
?not-end not if 
\ went to the end and didn't find 
true else false then ;

\ simply testing of character set
\ for password generating
: test 
 \ A-Z, a-z,0-9 -  62 symbols at all
 0 chset 62 type cr ;

\ test of password
: test-pass 0 pass pass-size type ;

\ generates symbol 
: gen ( -- sym )
  begin
    62  choose chset C@ dup
    ?good if exit else drop then
\ exit if unique
  again ; 

\ main thing!!!
\ generates whole password!

: doit
\ cycle for password's length
pass-size 0 do 
\ generates symbol and stores
\ it in password array
gen  i pass C!
loop ;

fill-chset 