Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #26441 > unrolled thread
| Started by | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| First post | 2013-10-12 19:07 -0700 |
| Last post | 2013-10-13 14:43 -0700 |
| Articles | 11 — 4 participants |
Back to article view | Back to comp.lang.forth
random password generator Paul Rubin <no.email@nospam.invalid> - 2013-10-12 19:07 -0700
Re: random password generator hughaguilar96@yahoo.com - 2013-10-12 22:01 -0700
Re: random password generator Paul Rubin <no.email@nospam.invalid> - 2013-10-12 22:32 -0700
Re: random password generator hughaguilar96@yahoo.com - 2013-10-12 22:44 -0700
Re: random password generator "WJ" <w_a_x_man@yahoo.com> - 2013-10-13 08:23 +0000
Re: random password generator Paul Rubin <no.email@nospam.invalid> - 2013-10-13 05:46 -0700
Re: random password generator "WJ" <w_a_x_man@yahoo.com> - 2013-10-13 17:09 +0000
Re: random password generator Bernd Paysan <bernd.paysan@gmx.de> - 2013-10-13 20:32 +0200
Re: random password generator Paul Rubin <no.email@nospam.invalid> - 2013-10-13 12:27 -0700
Re: random password generator Bernd Paysan <bernd.paysan@gmx.de> - 2013-10-13 22:52 +0200
Re: random password generator Paul Rubin <no.email@nospam.invalid> - 2013-10-13 14:43 -0700
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2013-10-12 19:07 -0700 |
| Subject | random password generator |
| Message-ID | <7x38o5zzwz.fsf@ruckus.brouhaha.com> |
#! /usr/bin/gforth 12 constant password_length variable rfile create buf 1 chars allot s" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=" ( addr u ) assert( dup 64 = ) 2drop constant alphabet : chk ( n -- ) assert( dup = ) drop ; : tchar ( c -- ) $3f AND alphabet + c@ emit ; : open-rand.1 ( -- wfileid ) s" /dev/urandom" r/o open-file 0 chk ; : open-rand ( -- ) open-rand.1 rfile ! ; : randombyte ( -- c ) buf 1 rfile @ read-file 0 chk 1 chk buf c@ ; : run ( -- ) open-rand password_length 0 do randombyte tchar loop cr ; run bye
[toc] | [next] | [standalone]
| From | hughaguilar96@yahoo.com |
|---|---|
| Date | 2013-10-12 22:01 -0700 |
| Message-ID | <dbbb6ae5-89ce-408e-b2bf-7663458f39a5@googlegroups.com> |
| In reply to | #26441 |
I glanced over your code. It is okay --- but it seems to have too many magic numbers in the code --- you could make it more robust in that it would allow you to change the alphabet without having to change the code. This is similar to code I wrote a long time ago (in high-school) for shuffling a deck of cards.
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2013-10-12 22:32 -0700 |
| Message-ID | <7xr4bpivlh.fsf@ruckus.brouhaha.com> |
| In reply to | #26441 |
Paul Rubin <no.email@nospam.invalid> writes: > : chk ( n -- ) assert( dup = ) drop ; That should say: : chk ( n n -- ) assert( 2dup = ) 2drop ;
[toc] | [prev] | [next] | [standalone]
| From | hughaguilar96@yahoo.com |
|---|---|
| Date | 2013-10-12 22:44 -0700 |
| Message-ID | <04651631-6c46-47c8-9153-6730b6110b46@googlegroups.com> |
| In reply to | #26447 |
On Saturday, October 12, 2013 10:32:58 PM UTC-7, Paul Rubin wrote: > Paul Rubin <no.email@nospam.invalid> writes: > > : chk ( n -- ) assert( dup = ) drop ; > > That should say: > > : chk ( n n -- ) assert( 2dup = ) 2drop ; ASSERT( is non-standard --- I would just stick with ABORT" which is ANS-Forth, and gives you a meaningful error message. Also, you shouldn't have all of this low-level error-checking code mixed in with your application code --- that belongs in a library, as it is essentially the same every time you work with files --- that is what I do in the novice package.
[toc] | [prev] | [next] | [standalone]
| From | "WJ" <w_a_x_man@yahoo.com> |
|---|---|
| Date | 2013-10-13 08:23 +0000 |
| Message-ID | <l3dla2$9vl$1@dont-email.me> |
| In reply to | #26441 |
Paul Rubin wrote:
> #! /usr/bin/gforth
> 12 constant password_length
> variable rfile
> create buf 1 chars allot
>
> s" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_="
> ( addr u ) assert( dup 64 = ) 2drop constant alphabet
>
> : chk ( n -- ) assert( dup = ) drop ;
> : tchar ( c -- ) $3f AND alphabet + c@ emit ;
> : open-rand.1 ( -- wfileid ) s" /dev/urandom" r/o open-file 0 chk ;
> : open-rand ( -- ) open-rand.1 rfile ! ;
> : randombyte ( -- c ) buf 1 rfile @ read-file 0 chk 1 chk buf c@ ;
> : run ( -- ) open-rand password_length 0 do randombyte tchar loop cr ;
>
> run bye
Ruby:
P_len = 12
alphabet =
[('a'..'z'),('A'..'Z'),('0'..'9'),'_'].map( &:to_a ).reduce( :+ )
srand
Array.new(P_len){ rand alphabet.size }.map{|n| alphabet[n,1] }.
join
==>"Enu1U9_Mfz0c"
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2013-10-13 05:46 -0700 |
| Message-ID | <7x4n8lcp9s.fsf@ruckus.brouhaha.com> |
| In reply to | #26459 |
"WJ" <w_a_x_man@yahoo.com> writes: > srand You have to use /dev/urandom which is a crypto RNG seeded by system entropy.
[toc] | [prev] | [next] | [standalone]
| From | "WJ" <w_a_x_man@yahoo.com> |
|---|---|
| Date | 2013-10-13 17:09 +0000 |
| Message-ID | <l3ek44$bjb$1@dont-email.me> |
| In reply to | #26459 |
WJ wrote:
> Paul Rubin wrote:
>
> > #! /usr/bin/gforth
> > 12 constant password_length
> > variable rfile
> > create buf 1 chars allot
> >
> > s" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_="
> > ( addr u ) assert( dup 64 = ) 2drop constant alphabet
> >
> > : chk ( n -- ) assert( dup = ) drop ;
> > : tchar ( c -- ) $3f AND alphabet + c@ emit ;
> > : open-rand.1 ( -- wfileid ) s" /dev/urandom" r/o open-file 0 chk ;
> > : open-rand ( -- ) open-rand.1 rfile ! ;
> > : randombyte ( -- c ) buf 1 rfile @ read-file 0 chk 1 chk buf c@ ;
> > : run ( -- ) open-rand password_length 0 do randombyte tchar loop cr ;
> >
> > run bye
>
> Ruby:
>
> P_len = 12
>
> alphabet =
> [('a'..'z'),('A'..'Z'),('0'..'9'),'_'].map( &:to_a ).reduce( :+ )
alphabet = ['a'..'z','A'..'Z','0'..'9','_'].map( &:to_a ).flatten
> srand
> Array.new(P_len){ rand alphabet.size }.map{|n| alphabet[n,1] }.
> join
> ==>"Enu1U9_Mfz0c"
[toc] | [prev] | [next] | [standalone]
| From | Bernd Paysan <bernd.paysan@gmx.de> |
|---|---|
| Date | 2013-10-13 20:32 +0200 |
| Message-ID | <l3ep0h$43g$1@online.de> |
| In reply to | #26441 |
Paul Rubin wrote: > #! /usr/bin/gforth > 12 constant password_length > variable rfile > create buf 1 chars allot > > s" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=" > ( addr u ) assert( dup 64 = ) 2drop constant alphabet > > : chk ( n -- ) assert( dup = ) drop ; > : tchar ( c -- ) $3f AND alphabet + c@ emit ; > : open-rand.1 ( -- wfileid ) s" /dev/urandom" r/o open-file 0 chk ; > : open-rand ( -- ) open-rand.1 rfile ! ; > : randombyte ( -- c ) buf 1 rfile @ read-file 0 chk 1 chk buf c@ ; > : run ( -- ) open-rand password_length 0 do randombyte tchar loop cr ; > > run bye This is a script. Things you just need to do once (e.g. open /dev/random) don't need to go into a definition. Just do them in interactive mode. Use throw on iors. If you have questions whether your alphabet really is 64 characters, add a ~~ right after the string once for debugging. Here's how I would do it: #! /usr/bin/gforth s" /dev/urandom" r/o open-file throw value rndfd : randombyte ( -- c ) rndfd key-file ; : >alphabet ( n -- c ) $3F and s" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=" drop + c@ ; : passwd ( len -- ) 0 ?DO randombyte >alphabet emit LOOP cr ; 12 passwd bye If you want to make that more robust for different alphabets (some passwords may have only digits and letters in it, or may not have uppercase letters to avoid confusion and whatever...), better do that: #! /usr/bin/gforth s" /dev/urandom" r/o open-file throw value rndfd : randomword ( -- u16 ) rndfd key-file rndfd key-file 8 lshift + ; : >alphabet ( u16 -- c ) s" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=" rot * 16 rshift + c@ ; : passwd ( len -- ) 0 ?DO randomword >alphabet emit LOOP cr ; 12 passwd bye BTW: Test what you have written, word by word. Your chk does not work, because "dup =" is always true. There is a reason why my >alphabet does neither contain the emit: This allows you to write checks for the word. -- Bernd Paysan "If you want it done right, you have to do it yourself" http://bernd-paysan.de/
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2013-10-13 12:27 -0700 |
| Message-ID | <7xbo2tc6pn.fsf@ruckus.brouhaha.com> |
| In reply to | #26479 |
Bernd Paysan <bernd.paysan@gmx.de> writes: > This is a script. Things you just need to do once (e.g. open /dev/random) > don't need to go into a definition. Just do them in interactive mode. Thanks! Hmm, ok, I thought it was easier to debug and test stuff by putting all the code into definitions, though in a very simple script like this it probably doesn't matter much. > Use throw on iors. Thanks, that's useful. I just found the info in the exceptions chapter of the gforth manual. That took a little searching because throw isn't in the word index (maybe you could add it): http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Word-Index.html > If you have questions whether your alphabet really is 64 characters, > add a ~~ right after the string once for debugging. Yeah the assert was kind of a built-in unit test. I generally prefer to leave things like that in programs if I don't mind the tiny bit of bloat. It's mostly to catch if I make a mistake in a later modification, rather than to check that the code works in the first place. > Here's how I would do it: > > #! /usr/bin/gforth > > s" /dev/urandom" r/o open-file throw value rndfd > : randombyte ( -- c ) rndfd key-file ; > : >alphabet ( n -- c ) $3F and > s" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=" > drop + c@ ; > : passwd ( len -- ) 0 ?DO randombyte >alphabet emit LOOP cr ; > > 12 passwd bye That is nice! I didn't know about key-file either. > : >alphabet ( u16 -- c ) > s" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=" > rot * 16 rshift + c@ ; Don't you mean : >alphabet ( u16 -- c ) s" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=" rot swap mod + c@ ; I considered something like that but I figured that the 6-bit alphabet (or even a 5-bit one) was more in the spirit of Forth minimalism. I haven't seen any recent systems that don't allow mixed case passwords but some obnoxious ones -require- the presence of both cases and digits (that's why I used 6 bits instead of 5). I decided that most passwords from this script have that because of their length, and I could just run the script several times if necessary. > BTW: Test what you have written, word by word. Your chk does not work, > because "dup =" is always true. Yes, result of a last-minute refactoring :(. I posted a correction.
[toc] | [prev] | [next] | [standalone]
| From | Bernd Paysan <bernd.paysan@gmx.de> |
|---|---|
| Date | 2013-10-13 22:52 +0200 |
| Message-ID | <l3f15p$ev2$1@online.de> |
| In reply to | #26480 |
Paul Rubin wrote: >> : >alphabet ( u16 -- c ) >>s" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=" >>rot * 16 rshift + c@ ; > > Don't you mean > > : >alphabet ( u16 -- c ) > s" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_=" > rot swap mod + c@ ; No, I mean multiply and then divide (with a right shift in this case). u16 is 0..ffff, and by dividing it is between [0..1[. That gives a uniform distribution over all characters in the string, and is typically faster than a modulus. -- Bernd Paysan "If you want it done right, you have to do it yourself" http://bernd-paysan.de/
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2013-10-13 14:43 -0700 |
| Message-ID | <7xppr8u9r7.fsf@ruckus.brouhaha.com> |
| In reply to | #26482 |
Bernd Paysan <bernd.paysan@gmx.de> writes: >>>rot * 16 rshift + c@ ; > No, I mean multiply and then divide (with a right shift in this > case). u16 is 0..ffff, and by dividing it is between [0..1[. That > gives a uniform distribution over all characters in the string, and is > typically faster than a modulus. Aha, very clever, it was confusing at first because small examples end up at 0. Basically the lower bits of the u16 are mostly thrown away, while modulus uses the lower bits and mostly throws away the upper ones. It works out about the same in the end. Both methods are slightly non-uniform unless the alphabet size exactly divides 2**16, but that's fine for this purpose (the effect on the output distribution's entropy is almost zero). Thanks again.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.forth
csiph-web