관리 메뉴

ㄴrㅎnㅂrㄹrㄱi

Another text converter/encripter (Lewis Carrolls Cipher) 본문

AUTOHOTKEY/레퍼런스

Another text converter/encripter (Lewis Carrolls Cipher)

님투 2008. 12. 30. 17:00
반응형

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.... Very Happy ) 

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"


;------------------------------------------------------------------------------
;  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: 


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

반응형

'AUTOHOTKEY > 레퍼런스' 카테고리의 다른 글

Function-Collection for AHK  (0) 2010.03.19
#AllowSameLineComments  (0) 2008.12.30
Creating a Keyboard Macro or Mouse Macro  (0) 2008.12.30
Click  (0) 2008.12.30
My Scripts  (0) 2007.11.08
Comments