Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #59033
| From | rickman <gnuarm@gmail.com> |
|---|---|
| Newsgroups | comp.lang.forth |
| Subject | Re: Rosetta: Caesar cipher |
| Date | 2017-05-11 01:50 -0400 |
| Organization | A noiseless patient Spider |
| Message-ID | <of0tsi$6u0$1@dont-email.me> (permalink) |
| References | <oet9tb$166r$1@gioia.aioe.org> <of09pp$k46$1@dont-email.me> <27244bc8-3cf8-445d-803e-bef86c1e6122@googlegroups.com> |
On 5/11/2017 12:12 AM, Julian Fondren wrote: > On Wednesday, May 10, 2017 at 7:07:29 PM UTC-5, rickman wrote: >> Here is my attempt. I had to work on this a bit as my string knowledge >> is a bit rusty... no, positively seized up! I couldn't remember how to >> create strings in the various modes. > > What do you mean by 'modes'? Compile, interpret. Seems interpretation is a tough mode to create strings in unless I am totally misunderstanding what I've read in the ANS standard. >> I'm not sure the test code will >> work universally. It runs under Win32Forth. > > It runs the same on many systems. Only VARIABLE ... ALLOT strikes me > as code to worry about. You should use CREATE if you want the ALLOT'd > dictionary space to be contiguous with the address the word returns. Ok. Thanks. >> marker rotc >> >> : ScreenChar ( char -- char flag ) \ Check for alpha char >> dup [char] A dup 26 + within if [char] A else >> dup [char] a dup 26 + within if [char] a else >> FALSE then then ; >> >> : RotChar ( char1 flag key -- char2 ) \ Rotate alpha char >> -rot tuck - rot + 26 mod + ; > > The 'flag' has a more interesting type than the stack comment > suggests. This is a good example of 'passing flags around' even so: > you test the char in ScreenChar and then, instead of rotating it at > once, you produce a value that's then tested again in RotCypher. Do > you anticipate any other use for ScreenChar's output than later > rotation? Look at the problem and figure out why I did it that way. There is a specific reason which isn't all that hard to see. Maybe I missed something that would make it simpler. > That ScreenChar leaves 'char' on the stack looks like an optimization > or rather an unwillingness to drop something you know you'll need > right after anyway. I'd take that as an indication that some other > factorization should be sought. But anyway, why worry? DROP <CONSTANT> > is easy fodder for an optimizer: > > : x 1 ; : y drop 1 ; ok > see x > 80839BF 4 # EBP SUB 83ED04 > 80839C2 EBX 0 [EBP] MOV 895D00 > 80839C5 1 # EBX MOV BB01000000 > 80839CA RET C3 ok > see y > 80839DF 1 # EBX MOV BB01000000 > 80839E4 RET C3 ok You've lost me. I don't write code thinking about optimizers or even optimization in general. I try to write code to be easy to understand and use. I can't remember the last time I wrote code that needed any sort of optimization. >> 0 value rotkey > > A VALUE could make sense. You could have a GUI element control the > 'encryption' by changing that. You could have words like REVERSIBLE > (rot13) or NAIVE (rot1) or SILLY (rot26) that set the value that a > later RotCypher would use... but then RotCypher sets rotkey itself, so > in the end this is just a local variable. > > So why not use a local variable? I have never gotten in a habit of locals. Why is that a significant thing? I only did this when I totally forgot my forth and tried to store it on the return stack inside the loop, lol, so I fixed it with a value. >> variable tmpstr 30 chars allot >> >> \ En/Decrypt the Caesar cipher with key >> : RotCypher ( caddr u key -- ) \ Output to tmpstr >> to rotkey >> 0 do ( caddr -- ) >> dup I + c@ ScreenChar dup if ( caddr char flag -- ) >> rotkey RotChar else >> drop then ( caddr char -- ) >> tmpstr I + c! ( caddr -- ) >> loop >> drop ; > > So you loop over the indexes of the string provided and use that to > index into the input and output strings, both. If you'd used VALUEs > for those two addresses, this same code could support in-place > rotation (at a cost of unnecessary writes) but could also produce the > rotated string in its ultimate destination, a prepared buffer in a > data structure or whatever, without the caller having to move the > string there as an additional step. This would also free your code > from having to care about how long the string might be. I started out writing this for modifications in place but decided to change it. Instead of adding the index, I incremented the address. But it was messy working with two addresses on the stack. Also, like I said, figuring out how to feed it a string where the data could be altered was not so easy. I understand why Hugh makes a big deal of the lack of array handling in Forth and has a library. I also have an array library but didn't want to clutter this solution with all that. Obviously I'm not so familiar with Forth that this comes easy to me. :( It is always so long between my using Forth that I forget much of what I had learned the last time. > Not to propose those VALUEs , really, but just to say: *if* you're > going to use a VALUE like this, there seems to be more use for source > address in a VALUE than for the rotation 'key'. I'm not following this at all. > Anyway, there's this alternative: loop over the addresses of the > source string's characters. This means you have to manage the > destination address differently. (And it's perfect for in-place > mutation.) It also gets source string off the data stack, which may > make the data stack easier to think about even if you end up > maintaining the same depths through the loop. > > : RotCypher ( c-addr u key -- ) > tmpstr 2swap bounds ?do ( key tmpstr ) > i c@ ScreenChar dup if fourth RotChar else drop then > over c! 1+ > loop 2drop ; Bounds? > Or with this rotchar: > > : rotchar ( key c -- c' ) > dup [char] A dup 26 + within if [char] A - + 26 mod [char] A + else > dup [char] a dup 26 + within if [char] a - + 26 mod [char] a + else > nip then then ; > > : RotCypher ( c-addr u key -- ) > tmpstr 2swap bounds ?do ( key tmpstr ) > over i c@ rotchar > over c! 1+ > loop 2drop ; > > This rotchar stands out as code that can be improved, but the rest is > fine. In your code RotChar looked pretty optimal on its own but > everything else looked more dubious. This rotchar, if improved, might > actually substantially improve the program. Improvements to your > ScreenChar or RotCypher would do less. I prefer this arrangement but > don't know if there's some design principle that it exhibits. > >> : "type" ( caddr u -- ) cr [char] " emit type [char] " emit .s ; >> >> cr cr .( Start testing) .s >> cr S" ABC mno 1, 2, 3" .s >> 2dup "type" >> tuck 1 RotCypher tmpstr swap 2dup "type" >> 2dup 25 RotCypher "type" >> >> >> -- >> >> Rick C > > : rot13: ( -- ) > source bounds ?do > 13 i c@ rotchar i c! > loop ; immediate > > rot13: : "glcr" ( pnqqe h -- ) pe [pune] " rzvg glcr [pune] " rzvg .f ; > rot13: > rot13: pe pe .( Fgneg grfgvat) .f > rot13: pe F" NOP zab 1, 2, 3" .f > rot13: 2qhc "glcr" > rot13: ghpx 1 EbgPlcure gzcfge fjnc 2qhc "glcr" > rot13: 2qhc 25 EbgPlcure "glcr" > > : secret ( -- c-addr u ) > rot13: f" 12345" ; > > somehow I can still see my password in that last example... It's late and I still need to pay my bills. I'll look at this again tomorrow to see if I can figure out source and bounds. -- Rick C
Back to comp.lang.forth | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Rosetta: Caesar cipher "Robert L." <No_spamming@noWhere_7073.org> - 2017-05-09 20:47 +0000
Re: Rosetta: Caesar cipher Joel Rees <joel.rees@gmail.com> - 2017-05-09 20:20 -0700
Re: Rosetta: Caesar cipher hughaguilar96@gmail.com - 2017-05-12 13:52 -0700
Re: Rosetta: Caesar cipher rickman <gnuarm@gmail.com> - 2017-05-10 20:07 -0400
Re: Rosetta: Caesar cipher Julian Fondren <julian.fondren@gmail.com> - 2017-05-10 21:12 -0700
Re: Rosetta: Caesar cipher rickman <gnuarm@gmail.com> - 2017-05-11 01:50 -0400
Re: Rosetta: Caesar cipher Julian Fondren <julian.fondren@gmail.com> - 2017-05-11 05:34 -0700
Re: Rosetta: Caesar cipher Alex <alex@rivadpm.com> - 2017-05-11 14:39 +0100
Re: Rosetta: Caesar cipher anton@mips.complang.tuwien.ac.at (Anton Ertl) - 2017-05-11 16:04 +0000
Re: Rosetta: Caesar cipher Alex <alex@rivadpm.com> - 2017-05-11 21:35 +0100
Re: Rosetta: Caesar cipher mhx@iae.nl - 2017-05-11 10:21 -0700
Re: Rosetta: Caesar cipher rickman <gnuarm@gmail.com> - 2017-05-12 13:41 -0400
csiph-web