AutoHotkey Community

It is currently May 27th, 2012, 12:24 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: December 23rd, 2008, 5:34 pm 
Offline

Joined: August 8th, 2008, 1:40 am
Posts: 36
As I posted on another thread, I have always wanted to write code to automaticlly encode and decode Lewis Carroll's Cipher.

I finally finished it and thought I would share. (I didn't check to see if it was already done, it would have burst my bubble.... :D )

I took the ideas/suggestions from some other threads to enable the user to change the limits (what characters are legal) and wrote 4 options in (2 with and same 2 without spaces), and while it probably isn't as secure as this thread, it's more than good enough for my purpouses.... I also did an overkill in documenting with comments what is happening and how it works so others who are new could learn quickly and easilly what I struggled with when I first found the "Albend translator".

Code:
;------------------------------------------------------------------------------
;  Lewis Carrolls Cipher
;  David Barnes 12/29/2008 14:18
;------------------------------------------------------------------------------


; Initialization
#NoEnv
#SingleInstance force
#EscapeChar  ; change escape char to prevent interference in text and key...(didn't help)
Sync := 0     ; for keeping track of position in key string
OutPutText =  ; obvious
Found := 0    ; toggle for last snippit
Replacement := Chr(13) . Chr(10)  ; value of carrige return (CR + LF) for last snippit


;   ***********************************
;   **** Current Available Options ****
;   ***********************************
; For letters only (no spaces) choose UpperLimit := 122 & LowerLimit := 65(26 letters *2)
; for letters only (including spaces) UpperLimit := 122 & LowerLimit := 64(26 letters * 2 + space)
; for all visible characters (incl spaces) UpperLimit := 126 & LowerLimit := 32(95 total)
; for all visible characters (no spaces) UpperLimit := 126 & LowerLimit := 33(94 total)
; For all AHK useable  visible characters (excludes: parenthesis, quotes * CR) UL=126 & LL=34 (92 total)
;
; *** User Set Options: ***

Key := "Nowisthetimeforallgoodmentocometotheaidoftheircountry"
UpperLimit := 126                     ; See **** Current Available Options **** above
LowerLimit := 34                      ; See **** Current Available Options **** Above

; *** end user options ***


InputBox, Action,, Copy text to convert into clipboard then select E=encode or D=decode:
StringUpper, Action, Action  ; converts %Action% (typed text) to uppercase
String := clipboard          ; gets text to encode or decode from the clipboard
KeyLen := StrLen(Key)        ; gets length of the key
Loop, Parse, String          ; read the text to encode or decode one character at a time
{
     Sync += 1                        ; increase key counter once each loop
                                      ; (seperate from A_Index in case of a key letter outside of range)

     ; get numbers
     KeyChar := SubStr(Key, Sync, 1)  ; gets current letter of key string
     KeyNum := Asc(KeyChar)           ; converts it to a number (ascii value)
     MsgNum := Asc(A_LoopField)       ; converts message letter to number

     ; Convert numbers per limits
     If (UpperLimit = 122 and LowerLimit = 65)       ;***** letters only no spaces (52 chars) *****
     {
          If (MsgNum > 96 AND MsgNum < 123)     ; lower case
               MsgNum -= 70
          Else If (MsgNum > 64 AND MsgNum < 91) ; upper case
               MsgNum -= 64
          Else MsgNum = 0                       ; not visible character
          If (KeyNum > 96 AND KeyNum < 123)     ; lower case
               KeyNum -= 70
          Else If (KeyNum > 64 AND KeyNum < 91) ; upper case
               KeyNum -= 64
          Else KeyNum = 0                       ; not visisble charcter
     }
     If (UpperLimit = 122 and LowerLimit = 64)       ;***** letters & spaces only (53 chars) *****
     {
          If (MsgNum > 96 AND MsgNum < 123)     ; lower case
               MsgNum -= 69
          Else If (MsgNum > 64 AND MsgNum < 91) ; upper case
               MsgNum -= 63
          Else If MsgNum = 32                   ; a space
               MsgNum = 1
          Else MsgNum = 0                       ; not visible character
          If (KeyNum > 96 AND KeyNum < 123)     ; lower case
               KeyNum -= 69
          Else If (KeyNum > 64 AND KeyNum < 91) ; upper case
               KeyNum -= 63
          Else If KeyNum = 32                   ; a space
               KeyNum = 1
          Else KeyNum = 0                       ; not visible character
     }
     If (UpperLimit = 126 and LowerLimit = 32)       ;***** all visible + spaces (95 chars) *****
     {
          If (MsgNum > 126 or MsgNum < 32)      ; not visible character or a space
               MsgNum = 0
          Else MsgNum -= 31
          Loop
          {
               If (KeyNum > 126 or KeyNum < 32) ; if key char not visible char or space,
               {                                ; get & use next key char
                    Sync +=1                    ; this is why we didn't use A_Index
                    If (Sync = KeyLen + 1)
                         Sync = 1
                    KeyChar := SubStr(Key, Sync, 1)
                    KeyNum := Asc(KeyChar)
               }
               Else break
               If (A_Index = 999)               ; just in case of an error, prevent endless loop
                    ExitApp
          }
          KeyNum -= 31
     }
     If (UpperLimit = 126 and LowerLimit = 33)       ;***** all visible, no spaces (94 chars) *****
     {
          If (MsgNum > 126 or MsgNum < 33)      ; not visible character or a space
               MsgNum = 0
          Else MsgNum -= 32
          Loop
          {
               If (KeyNum > 126 or KeyNum < 33) ; if key char not visible char or space
               {                                ; get & use next key char
                    Sync +=1                    ; this is why we didn't use A_Index
                    If (Sync = KeyLen + 1)
                         Sync = 1
                    KeyChar := SubStr(Key, Sync, 1)
                    KeyNum := Asc(KeyChar)
               }
               Else break
               If (A_Index = 999)               ; just in case of an error, prevent endless loop
                    ExitApp
          }             
          KeyNum -= 32
     }
     If (UpperLimit = 126 and LowerLimit = 34)     ;***** AHK visible + spaces (92 chars no CR) *****
     {
          If (MsgNum > 126 or MsgNum < 32)      ; not visible character
               MsgNum := -3
          Else MsgNum -= 34
          If (MsgNum < 8)                       ; eliminates ( & )
               MsgNum += 2
          If (MsgNum < 3)                       ; eliminates "
               MsgNum += 1
          Loop
          {
               If (KeyNum > 126 or KeyNum < 32  ; AHK valid visible characters
               or KeyNum = 34 or KeyNum = 40 or KeyNum = 41)
               {                                ; get & use next key char
                    MsgBox, invalid key character for limits chosen
                    Sync +=1                    ; this is why we didn't use A_Index
                    If (Sync = KeyLen + 1)
                         Sync = 1
                    KeyChar := SubStr(Key, Sync, 1)
                    KeyNum := Asc(KeyChar)
               }
               Else break
               If (A_Index = 999)               ; just in case of an error, prevent endless loop
                    ExitApp
          }             
          KeyNum -= 34
          If (KeyNum < 8)                       ; eliminates ( & )
               KeyNum += 2
          If (KeyNum < 3)                       ; eliminates "
               KeyNum += 1
     }


     ; do math (actual conversion)
     If (Action = "E")                          ; Encoding...
          NewNum := MsgNum + KeyNum - 1
     Else                                       ; Decoding...
          NewNum := MsgNum - KeyNum + 1

     ; Convert numbers back to asci range
     If (UpperLimit = 122 and LowerLimit = 65)       ;***** letters only no spaces (52 chars)*****
     {
          If (NewNum < 0)                       ; get NewNum back into 0-52 range
               NewNum += 53
          Else If (NewNum > 52)
               NewNum -= 53

          If (NewNum > 26)                      ; putting back onto ascii range(upper case)
               NewNum += 70
          Else If (NewNum < 27)                 ; putting back onto ascii range(lower case)
               NewNum += 64
     }
     If (UpperLimit = 122 and LowerLimit = 64)       ;***** letters & spaces only(53 + errors) *****
     {
          If (NewNum < 0)                       ; get NewNum back into 0-53 range
               NewNum += 54
          Else If (NewNum > 53)
               NewNum -= 54

          If (NewNum > 27)                      ; putting back onto ascii range(upper case)
               NewNum += 69
          If (NewNum < 28)                      ; putting back onto ascii range(lower case)
               NewNum += 63
          If (NewNum = 64)                      ; putting back onto ascii range(space)
               NewNum = 32
     }
     If (UpperLimit = 126 and LowerLimit = 33)       ;***** all visible, no spaces (94 chars) *****
     {
          If (NewNum < 0)                       ; get NewNum back into 0-94 range
               NewNum += 95
          If (NewNum > 94)
               NewNum -= 95

          NewNum +=32                           ; putting back onto ascii range
     }
     If (UpperLimit = 126 and LowerLimit = 32)       ;***** all visible + spaces (95 chars) *****
     {
          If (NewNum < 0)                       ; get NewNum back into 0-95 range
               NewNum += 96
          Else If (NewNum > 95)
               NewNum -= 96

          NewNum +=31                           ; putting back onto ascii range
     }
     If (UpperLimit = 126 and LowerLimit = 34)       ;***** all AHK visible + spaces (92 chars) *****
     {
          If (NewNum < 1)                       ; get NewNum back into 0-92 range
               NewNum += 92
          Else If (NewNum > 92)
               NewNum -= 92
          NewNum +=34                           ; putting back onto ascii range
          If (NewNum < 42)                      ; fixing ( & )
               NewNum -= 2
          If (NewNum < 35)                      ; fixing "
               NewNum -= 1
     }

     ; convert back to characters and add to output (& reset key counter)
     CurNewChar := Chr(NewNum)                  ; change ascii number back to a letter
     OutputText .= CurNewChar                   ; add this letter to output
     If (Sync = KeyLen)                         ; reset key char counter if reached end of key string
          Sync = 0
}

; convert errors to carrige returns to format text for nice looks (aka, last snippit)
If (Action = "D") and (UpperLimit != 126 or LowerLimit != 34)  ; only if decoding and not AHK charset
{
     Loop, % StrLen(OutputText) - 1             ; loop one less because compare 2 characters @ a time
     {
          If (Found = 1)                        ; if last loop iteration found 2 consecutive errors
          {
               Found = 0                        ; reset toggle, skip this time, & go to next char set
               Continue
          }
          AnalyzeChar := SubStr(OutputText, A_Index, 2)         ; looks at 2 characters
          StringSplit, AnalyzeChar, AnalyzeChar                 ; splits 2 chars into AnalyzeChar1&2
          ACN1 := Asc(AnalyzeChar1)                             ; gets ascii number of each
          ACN2 := Asc(AnalyzeChar2) 
          If (ACN1 = LowerLimit - 1 and ACN2 = LowerLimit - 1)  ; if both chars are errors(< lower range)
          {
               OutputText := SubStr(OutputText, 1, A_Index - 1) ; repl w/ CR value
                             . Replacement
                             . SubStr(OutputText, A_Index + 2)
               Found = 1                                        ; flip toggle
          }
     }
}
Sleep, 100
clipboard =
clipboard := OutputText                                         ; Loads output to clipboard
MsgBox, Converted text is now in the clipboard.
ExitApp


While that looks like quite a large program, I condensed it to only what is needed to do one option and this is the actual code:

Code:
Albend:
Albend =
KeyLen := StrLen(Key)
Sync := 0
Loop, Parse, Raw
{
     Sync += 1
     MsgNum := Asc(A_LoopField)
     KeyChar := SubStr(Key, Sync, 1)
     KeyNum := Asc(KeyChar)
     If (MsgNum > 126 or MsgNum < 32)
          MsgNum = 0
     Else MsgNum -= 31           
     KeyNum -= 31
     NewNum := MsgNum - KeyNum + 1 ; Do Math
     If (NewNum < 0)
          NewNum += 96
     Else If (NewNum > 95)
          NewNum -= 96
     NewNum +=31
     CurNewChar := Chr(NewNum)
     Albend .= CurNewChar
     If (Sync = KeyLen)
          Sync = 0
}
Return


So, Thanks again HogoV!! :D

Edit to correct a couple errors and add AHK acceptable characters option(34-126)...


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 12th, 2009, 9:59 pm 
Offline

Joined: March 12th, 2009, 7:22 pm
Posts: 4
No doubt you know this already
since you seem to be very competent with your scripting
i could never dream of making this script

i did edit it so that if you press cancel it doesn't show the box confirming that the text has been coded/decoded

here it is

Code:
;------------------------------------------------------------------------------
;  Lewis Carrolls Cipher
;  David Barnes 12/29/2008 14:18
;------------------------------------------------------------------------------


; Initialization
#NoEnv
#SingleInstance force
#EscapeChar  ; change escape char to prevent interference in text and key...(didn't help)
Sync := 0     ; for keeping track of position in key string
OutPutText =  ; obvious
Found := 0    ; toggle for last snippit
Replacement := Chr(13) . Chr(10)  ; value of carrige return (CR + LF) for last snippit


;   ***********************************
;   **** Current Available Options ****
;   ***********************************
; For letters only (no spaces) choose UpperLimit := 122 & LowerLimit := 65(26 letters *2)
; for letters only (including spaces) UpperLimit := 122 & LowerLimit := 64(26 letters * 2 + space)
; for all visible characters (incl spaces) UpperLimit := 126 & LowerLimit := 32(95 total)
; for all visible characters (no spaces) UpperLimit := 126 & LowerLimit := 33(94 total)
; For all AHK useable  visible characters (excludes: parenthesis, quotes * CR) UL=126 & LL=34 (92 total)
;
; *** User Set Options: ***

Key := "Nowisthetimeforallgoodmentocometotheaidoftheircountry"
UpperLimit := 126                     ; See **** Current Available Options **** above
LowerLimit := 34                      ; See **** Current Available Options **** Above

; *** end user options ***


InputBox, Action,, Copy text to convert into clipboard then select E=encode or D=decode:
if errorlevel = 1                  ; added by silurian
  exitapp                            ;yay
StringUpper, Action, Action  ; converts %Action% (typed text) to uppercase
String := clipboard          ; gets text to encode or decode from the clipboard
KeyLen := StrLen(Key)        ; gets length of the key
Loop, Parse, String          ; read the text to encode or decode one character at a time
{
     Sync += 1                        ; increase key counter once each loop
                                      ; (seperate from A_Index in case of a key letter outside of range)

     ; get numbers
     KeyChar := SubStr(Key, Sync, 1)  ; gets current letter of key string
     KeyNum := Asc(KeyChar)           ; converts it to a number (ascii value)
     MsgNum := Asc(A_LoopField)       ; converts message letter to number

     ; Convert numbers per limits
     If (UpperLimit = 122 and LowerLimit = 65)       ;***** letters only no spaces (52 chars) *****
     {
          If (MsgNum > 96 AND MsgNum < 123)     ; lower case
               MsgNum -= 70
          Else If (MsgNum > 64 AND MsgNum < 91) ; upper case
               MsgNum -= 64
          Else MsgNum = 0                       ; not visible character
          If (KeyNum > 96 AND KeyNum < 123)     ; lower case
               KeyNum -= 70
          Else If (KeyNum > 64 AND KeyNum < 91) ; upper case
               KeyNum -= 64
          Else KeyNum = 0                       ; not visisble charcter
     }
     If (UpperLimit = 122 and LowerLimit = 64)       ;***** letters & spaces only (53 chars) *****
     {
          If (MsgNum > 96 AND MsgNum < 123)     ; lower case
               MsgNum -= 69
          Else If (MsgNum > 64 AND MsgNum < 91) ; upper case
               MsgNum -= 63
          Else If MsgNum = 32                   ; a space
               MsgNum = 1
          Else MsgNum = 0                       ; not visible character
          If (KeyNum > 96 AND KeyNum < 123)     ; lower case
               KeyNum -= 69
          Else If (KeyNum > 64 AND KeyNum < 91) ; upper case
               KeyNum -= 63
          Else If KeyNum = 32                   ; a space
               KeyNum = 1
          Else KeyNum = 0                       ; not visible character
     }
     If (UpperLimit = 126 and LowerLimit = 32)       ;***** all visible + spaces (95 chars) *****
     {
          If (MsgNum > 126 or MsgNum < 32)      ; not visible character or a space
               MsgNum = 0
          Else MsgNum -= 31
          Loop
          {
               If (KeyNum > 126 or KeyNum < 32) ; if key char not visible char or space,
               {                                ; get & use next key char
                    Sync +=1                    ; this is why we didn't use A_Index
                    If (Sync = KeyLen + 1)
                         Sync = 1
                    KeyChar := SubStr(Key, Sync, 1)
                    KeyNum := Asc(KeyChar)
               }
               Else break
               If (A_Index = 999)               ; just in case of an error, prevent endless loop
                    ExitApp
          }
          KeyNum -= 31
     }
     If (UpperLimit = 126 and LowerLimit = 33)       ;***** all visible, no spaces (94 chars) *****
     {
          If (MsgNum > 126 or MsgNum < 33)      ; not visible character or a space
               MsgNum = 0
          Else MsgNum -= 32
          Loop
          {
               If (KeyNum > 126 or KeyNum < 33) ; if key char not visible char or space
               {                                ; get & use next key char
                    Sync +=1                    ; this is why we didn't use A_Index
                    If (Sync = KeyLen + 1)
                         Sync = 1
                    KeyChar := SubStr(Key, Sync, 1)
                    KeyNum := Asc(KeyChar)
               }
               Else break
               If (A_Index = 999)               ; just in case of an error, prevent endless loop
                    ExitApp
          }             
          KeyNum -= 32
     }
     If (UpperLimit = 126 and LowerLimit = 34)     ;***** AHK visible + spaces (92 chars no CR) *****
     {
          If (MsgNum > 126 or MsgNum < 32)      ; not visible character
               MsgNum := -3
          Else MsgNum -= 34
          If (MsgNum < 8)                       ; eliminates ( & )
               MsgNum += 2
          If (MsgNum < 3)                       ; eliminates "
               MsgNum += 1
          Loop
          {
               If (KeyNum > 126 or KeyNum < 32  ; AHK valid visible characters
               or KeyNum = 34 or KeyNum = 40 or KeyNum = 41)
               {                                ; get & use next key char
                    MsgBox, invalid key character for limits chosen
                    Sync +=1                    ; this is why we didn't use A_Index
                    If (Sync = KeyLen + 1)
                         Sync = 1
                    KeyChar := SubStr(Key, Sync, 1)
                    KeyNum := Asc(KeyChar)
               }
               Else break
               If (A_Index = 999)               ; just in case of an error, prevent endless loop
                    ExitApp
          }             
          KeyNum -= 34
          If (KeyNum < 8)                       ; eliminates ( & )
               KeyNum += 2
          If (KeyNum < 3)                       ; eliminates "
               KeyNum += 1
     }


     ; do math (actual conversion)
     If (Action = "E")                          ; Encoding...
          NewNum := MsgNum + KeyNum - 1
     Else                                       ; Decoding...
          NewNum := MsgNum - KeyNum + 1

     ; Convert numbers back to asci range
     If (UpperLimit = 122 and LowerLimit = 65)       ;***** letters only no spaces (52 chars)*****
     {
          If (NewNum < 0)                       ; get NewNum back into 0-52 range
               NewNum += 53
          Else If (NewNum > 52)
               NewNum -= 53

          If (NewNum > 26)                      ; putting back onto ascii range(upper case)
               NewNum += 70
          Else If (NewNum < 27)                 ; putting back onto ascii range(lower case)
               NewNum += 64
     }
     If (UpperLimit = 122 and LowerLimit = 64)       ;***** letters & spaces only(53 + errors) *****
     {
          If (NewNum < 0)                       ; get NewNum back into 0-53 range
               NewNum += 54
          Else If (NewNum > 53)
               NewNum -= 54

          If (NewNum > 27)                      ; putting back onto ascii range(upper case)
               NewNum += 69
          If (NewNum < 28)                      ; putting back onto ascii range(lower case)
               NewNum += 63
          If (NewNum = 64)                      ; putting back onto ascii range(space)
               NewNum = 32
     }
     If (UpperLimit = 126 and LowerLimit = 33)       ;***** all visible, no spaces (94 chars) *****
     {
          If (NewNum < 0)                       ; get NewNum back into 0-94 range
               NewNum += 95
          If (NewNum > 94)
               NewNum -= 95

          NewNum +=32                           ; putting back onto ascii range
     }
     If (UpperLimit = 126 and LowerLimit = 32)       ;***** all visible + spaces (95 chars) *****
     {
          If (NewNum < 0)                       ; get NewNum back into 0-95 range
               NewNum += 96
          Else If (NewNum > 95)
               NewNum -= 96

          NewNum +=31                           ; putting back onto ascii range
     }
     If (UpperLimit = 126 and LowerLimit = 34)       ;***** all AHK visible + spaces (92 chars) *****
     {
          If (NewNum < 1)                       ; get NewNum back into 0-92 range
               NewNum += 92
          Else If (NewNum > 92)
               NewNum -= 92
          NewNum +=34                           ; putting back onto ascii range
          If (NewNum < 42)                      ; fixing ( & )
               NewNum -= 2
          If (NewNum < 35)                      ; fixing "
               NewNum -= 1
     }

     ; convert back to characters and add to output (& reset key counter)
     CurNewChar := Chr(NewNum)                  ; change ascii number back to a letter
     OutputText .= CurNewChar                   ; add this letter to output
     If (Sync = KeyLen)                         ; reset key char counter if reached end of key string
          Sync = 0
}

; convert errors to carrige returns to format text for nice looks (aka, last snippit)
If (Action = "D") and (UpperLimit != 126 or LowerLimit != 34)  ; only if decoding and not AHK charset
{
     Loop, % StrLen(OutputText) - 1             ; loop one less because compare 2 characters @ a time
     {
          If (Found = 1)                        ; if last loop iteration found 2 consecutive errors
          {
               Found = 0                        ; reset toggle, skip this time, & go to next char set
               Continue
          }
          AnalyzeChar := SubStr(OutputText, A_Index, 2)         ; looks at 2 characters
          StringSplit, AnalyzeChar, AnalyzeChar                 ; splits 2 chars into AnalyzeChar1&2
          ACN1 := Asc(AnalyzeChar1)                             ; gets ascii number of each
          ACN2 := Asc(AnalyzeChar2) 
          If (ACN1 = LowerLimit - 1 and ACN2 = LowerLimit - 1)  ; if both chars are errors(< lower range)
          {
               OutputText := SubStr(OutputText, 1, A_Index - 1) ; repl w/ CR value
                             . Replacement
                             . SubStr(OutputText, A_Index + 2)
               Found = 1                                        ; flip toggle
          }
     }
}
Sleep, 100
clipboard =
clipboard := OutputText                                         ; Loads output to clipboard
MsgBox, Converted text is now in the clipboard.
ExitApp


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 12th, 2009, 10:26 pm 
Online
User avatar

Joined: May 5th, 2007, 7:24 pm
Posts: 1240
Location: Seville, Spain
You can create your own functions() you know.

_________________
fincs
Highly recommended: AutoHotkey_L (see why) (all my code snippets require it)
Formal request to polyethene - I support the unity of the AutoHotkey community
Get SciTE4AutoHotkey v3.0.00 (Release Candidate)
[My project list]


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bon, Google Feedfetcher, SKAN and 5 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group