(*
Met ctrl-A selecteer je de gehele inhoud van deze html-file als platte tekst, geschikt voor forth. Met ctrl-C copieer je dat. Met ctrl-V plak je het in de terminal of in een file voor een platte-tekst editor.

  Wachtwoordmaker (an aug2024)

Voor forthbijeenkomst 05okt2024 .W ( len x -- ) \ druk wachtwoord af len = lengte vh wachtwoord x = een willekeurig getal Vier varianten: .W0 - Basisprogramma .W1 - Spatie om de 4 tekens .W2 - Niet te veel leestekens .W2a .W2b - Alternatieven voor .W2 .W3 - Vermijd 0 1 I O l | .W3a - Alternatief voor .W3 noForth woorden: CH UMIN ?EXIT BOUNDS M, SCAN FOR NEXT *)

\   .W0 - Basisprogramma

decimal
111 value (RND)
: RND  ( -- x )         \ Genereer een random getal.
    (rnd) 31421 * 6927 + dup to (rnd) ;
: GET ( -- ch )         \ Genereer random ch, 34% kans op leesteken
    rnd 94 mod ch ! + ; \ 94 zichtbare tekens, ! t/m ~
: .W0 ( len x -- )      \ Druk wachtwoord af
    to (rnd) 40 umin
    for get emit next space ;


\   .W1 - Spatie om de 4 tekens

: ?SPACE ( i -- ) 3 and ?exit space ;    \ Spatie bij veelvoud van 4
: .W1    ( len x -- )
    to (rnd) 40 umin 0
    ?do i ?space get emit loop space ;


\   .W2 - Niet te veel leestekens

\ Hors concours:
: GET' ( -- ch ) rnd 86 mod ch % + ; \ ch % tm ch z : .W' ( len x -- ) to (rnd) 40 umin for get' emit next space ;


\ Kans op leestekens in procenten
222 value %OTHERS    25 to %others
\ Tekenselectie via berekening
(*
ASCII  33       48       58      65       91      97       123
        !..../   0....9   :...@   A....Z   [...`   a....z   {...~
aantal    15       10       7       26       6       26       4
*)
: ALFANUM ( -- ch )     \ 62 tekens
    rnd 62 mod ch 0 +
    dup ch 9 > 7 and +
    dup ch Z > 6 and + ;
: OTHER   ( -- ch )     \ 32 tekens
    rnd 31 and ch ! +
    dup ch 0 < ?exit 10 +
    dup ch A < ?exit 26 +
    dup ch a < ?exit 26 + ;
: GET2    ( -- ch )
    rnd 100 mod %others <
    if other exit then alfanum ;
: .W2     ( len x -- )
    to (rnd) 40 umin
    for get2 emit i ?space next ;


\   .W2a - Alternatief voor .W2

\ Tekenselectie via lijst van tekens
create (OTHERs) ( -- adr )
    bl parse !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~   dup c, m, align
: OTHER   ( -- ch ) (others) count rnd swap mod + c@ ;
: ALFANUM ( -- ch )
    s" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    rnd swap mod + c@ ;
: GET2a   ( -- ch )
    rnd 100 mod %others <
    if other exit then alfanum ;
: .W2a    ( len x -- )
    to (rnd) 40 umin
    for get2a emit i ?space next ;


\   .W2b - Nog een alternatief voor .W2

\ Precieze aantal leestekens in procenten
: VERWISSEL ( a1 a2 -- )    \ Verwissel de karakters op a1 en a2
    over c@ over        ( a1  a2 a1@ a2 )
    2swap c@ swap       ( a1@ a2 a2@ a1 )
    c! c! ;
: HERSCHIK  ( adr len -- )  \ Haal de string overhoop
    dup
    for  2dup >r dup    ( .. adr adr      r: len )
         rnd r> mod i   ( .. adr adr i? i )
         d+ verwissel
    next 2drop ;
: TYPE4 ( a n -- ) for count emit i ?space next drop ;
: .W2b  ( len x -- )
    to (rnd) 40 umin
    dup %others 100 */              ( len #others )
    <# dup    for other   hold next                     \ buffer
       2dup - for alfanum hold next
    #> 2dup type4 5 spaces 2dup herschik type4 ;


\   .W3 - Vermijd 0 1 I O l |

\ Tekenlijst aanpassen
create OTHER   ( -- ch )                            \ zonder "|
    s" !#$%&'()*+,-./:;<=>?@[\]^_`{}~"
    dup c, m, align
    does> count rnd swap mod + c@ ;

    :noname does> count rnd swap mod + c@ ;
create ALFANUM ( -- ch )                            \ zonder 01IOl
    s" 23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
    dup c, m, align
    execute

: GET3 ( -- ch )
    rnd 100 mod %others <
    if other exit then alfanum ;
: .W3  ( len x -- )
    to (rnd) 40 umin
    for get3 emit i ?space next ;


\   .W3a - Alternatief voor .W3

\ Ongewenste tekenens achteraf uitschakelen
: GET3a ( -- ch )
    0                       ( dummy )
    begin drop
          get2 dup          ( ch ch ) \ kan ook met GET2a
          s" 01IOl|"        ( a n )   \ taboestring
          bounds rot scan = ( ch ? )  \ ch niet in taboestring?
    until ;
: .W3a  ( len x -- )
    to (rnd) 40 umin
    for get3a emit i ?space next ;


(*
: BOUNDS ( a n -- a+n a ) over + swap ;
: M,     ( a n -- )       bounds ?do i c, loop ;
: SCAN   ( tot van ch -- tot van' )
    >r
    begin 2dup >
    while count r@ =
    until 1-            \ terug naar de positie van ch
    then  r> drop ;

Over FOR-NEXT

FOR-NEXT zit niet in de standaard. In noForth geldt: • i is hetzelfde als r@ en dus manipuleerbaar • i daalt van x-1 in de eerste doorloop naar 0 in de laatste doorloop • x FOR..NEXT wordt altijd x (unsigned) maal doorlopen, dus: 0 FOR..NEXT wordt 0 maal doorlopen 1 FOR..NEXT wordt 1 maal doorlopen -1 FOR..NEXT wordt hx FF..F maal doorlopen Maar bijvoorbeeld ... (citaat): " In eForth the following FOR .. NEXT properties are noteworthy: • at least one iteration will be performed (the loop counter is equal to the input of FOR) • the "loop count" will be "one-too-many" compared with standard loop structures (e.g. DO .. LOOP) • the number of iterations is limited to 32768 (from the largest positive integer down to zero) "
*)
\ VALUE vraagt in forth m en forth r geen beginwaarde.
.s \ 3 values, (RND) %others #others