Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #59033

Re: Rosetta: Caesar cipher

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>

Show all headers | View raw


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


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