Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Vigenère cipher method

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Vigenère cipher method

    Reading the thread Easy hide strings from casual viewing of Wayne Diamond I remembered one of my first programs that I wrote. This program was made by requeriment of a computer center manager to obfuscate the payroll file of own computer center in order to hide the information contained to his night operators.

    I can remember some details about the method used on this program, was a variation of Vigenère method for EBCDIC code, written with Assembler/360 on card punch, for a IBM main frame. Was in 1967. During the 60's decade this method was considered robust.

    Here is the version for ASCII using PB as language. Has a limitation, only is valid for first 127 ASCII characters.


    Code:
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Vigenere.bas                  by Jordi Vallès        version 1a     11/07/2008
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ' Simple but efective and fast cypher method. Appropriate to hide information to
    ' operators or employees for prevent casual viewing of some critical information
    ' like payroll data, personnel files, etc.
    ' It's based on polyalphabetic substitution. This method is not inteded to
    ' protect sensitive data to experienced crackers and spies.
    '
    ' This program works only for 127 first ASCII characters. For complete 256 chars
    ' need some modifications.
    '
    ' Interesting information and history about Blaise de Vigenère (1523-1596) and
    ' cipher methods based on polyalphabetic substitution can be found on:
    '   Wikipedia: Vigenère cipher and
    '   Wkipedia: Polyalphabetic cipher
    '
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    '  - Program developed and tested with PowerBASIC for Windows (PB/Win 8.04) on
    '    PC HP Pavilion m7760 1.80 GHz with Windows Vista Home Premium.
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' SED_PBWIN
    
    #COMPILE EXE "Vigenere.exe"
    #DIM ALL
    
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    FUNCTION PBMAIN() AS LONG
       LOCAL textI, textC, textD, tkey AS STRING
    
       textI = "Go placidly amid the noise & haste, and remember what peace there may be in silence. " + _
               "As far as possible, without surrender, be on good terms with all persons. Speak your " + _
               "truth quietly and clearly; And listen to others, even the dull and ignorant; they too " + _
               "have their story."
    
       tkey = "This is my Key"
    
       CALL Cypher(tkey, textI, textC)
    
       CALL DeCypher(tkey, textC, textD)
    
       MSGBOX "- Original text:" + $CRLF + textI + $CRLF + $CRLF + _
              "- Text Cyphered:" + $CRLF + textC + $CRLF + $CRLF + _
              "- Text DeCyphered:" + $CRLF + textD
    END FUNCTION
    
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    SUB Cypher(keyt AS STRING, text1 AS STRING, text2 AS STRING)
       LOCAL i, j, k, n AS LONG
       LOCAL letter AS BYTE PTR
    
       letter = STRPTR(text1)
       text2  = SPACE$(LEN(text1))
    
       'loop through all characters of the text to be cyphered
       FOR j = 1 TO LEN(text1)
          'get the current character of the key
          k =  ASC(MID$(keyt, j MOD LEN(keyt)+1, 1))
          'get the numeric value of the current key character
          i = k - 31
          'shift the character of the text, rotate if necessary
          n = @letter + i
          IF n > 126 THEN n = n - 95
          'append to the ciphered string
          MID$(text2,j) = CHR$(n)
          INCR letter
       NEXT j
    END SUB
    
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    SUB DeCypher(keyt AS STRING, text1 AS STRING, text2 AS STRING)
       LOCAL i, j, k, n AS LONG
       LOCAL letter AS BYTE PTR
    
       letter = STRPTR(text1)
       text2  = SPACE$(LEN(text1))
    
       'loop through all characters of the encrypted string
       FOR j = 1 TO LEN(text1)
          'get the current character of the key
          k =  ASC(MID$(keyt, j MOD LEN(keyt)+1, 1))
          'get the numeric value of the current key character
          i = k - 31
          'shift the character of the text, rotate if necessary
          n = @letter - i
          IF n < 32 THEN n = n + 95
          'append to the deciphered string
          MID$(text2,j) = CHR$(n)
          INCR letter
       NEXT j
    END SUB
    
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    'eof

  • #2
    Thank you very much,

    till know I just read about this cypher, now I can finally understand it

    Here comes little performance tweak, I get 7x - 8x faster execution speed comparing to original.

    Whole trick is in my favourite technique of array memory overlays.
    When tested with 8000 repetitions of original string ( ~= 2MB of data ), speed gain in this version is about 7x to 8x.


    Petr

    Code:
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Vigenere.bas                  by Jordi Valle`s        version 1b     13/07/2008
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ' Simple but efective and fast cypher method. Appropriate to hide information to
    ' operators or employees for prevent casual viewing of some critical information
    ' like payroll data, personnel files, etc.
    ' It's based on polyalphabetic substitution. This method is not inteded to
    ' protect sensitive data to experienced crackers and spies.
    '
    ' This program works only for 127 first ASCII characters. For complete 256 chars
    ' need some modifications.
    '
    ' Interesting information and history about Blaise de Vigene`re (1523-1596) and
    ' cipher methods based on polyalphabetic substitution can be found on:
    '   Wikipedia: Vigene`re cipher and
    '   Wkipedia: Polyalphabetic cipher
    '
    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    '  - Program developed and tested with PowerBASIC for Windows (PB/Win 8.04) on
    '    PC HP Pavilion m7760 1.80 GHz with Windows Vista Home Premium.
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' v1b - Minor tweaks in performance of the algo, speed gain about 7x - 8x
    '       by Petr Schreiber
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' SED_PBWIN
    
    #COMPILE EXE "Vigenere.exe"
    #DIM ALL
    
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    FUNCTION PBMAIN() AS LONG
       LOCAL textI, textC, textD, tkey AS STRING
    
       textI = "Go placidly amid the noise & haste, and remember what peace there may be in silence. " + _
               "As far as possible, without surrender, be on good terms with all persons. Speak your " + _
               "truth quietly and clearly; And listen to others, even the dull and ignorant; they too " + _
               "have their story."
    
       tkey = "This is my Key"
    
       CALL Cypher(tkey, textI, textC)
    
       CALL DeCypher(tkey, textC, textD)
    
       MSGBOX "- Original text:" + $CRLF + textI + $CRLF + $CRLF + _
              "- Text Cyphered:" + $CRLF + textC + $CRLF + $CRLF + _
              "- Text DeCyphered:" + $CRLF + textD
    
    END FUNCTION
    
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    SUB Cypher(keyt AS STRING, text1 AS STRING, text2 AS STRING)
       REGISTER j AS LONG, i AS LONG
       LOCAL n AS LONG
    
       DIM ByteKeyT(1 TO LEN(keyt)) AS LOCAL BYTE AT STRPTR(keyt)
       DIM ByteTextIn(1 TO LEN(Text1)) AS LOCAL BYTE AT STRPTR(text1)
    
       'preallocate characters
       text2  = SPACE$(LEN(text1))
    
       DIM ByteTextOut(1 TO LEN(text2)) AS LOCAL BYTE AT STRPTR(text2)
    
    
       'loop through all characters of the text to be cyphered
       FOR j = 1 TO LEN(text1)
    
          'get the current character of the key
          i = ByteKeyT(j MOD LEN(keyt)+1)-31
    
          'get the numeric value of the current key character
          n = ByteTextIn(j) + i
          
          'shift the character of the text, rotate if necessary
          IF n > 126 THEN n = n - 95
    
          'insert character to the ciphered string
          ByteTextOut(j) = n
    
       NEXT j
    
    END SUB
    
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    SUB DeCypher(keyt AS STRING, text1 AS STRING, text2 AS STRING)
       REGISTER j AS LONG, i AS LONG
       LOCAL n AS LONG
    
       DIM ByteKeyT(1 TO LEN(keyt)) AS LOCAL BYTE AT STRPTR(keyt)
       DIM ByteTextIn(1 TO LEN(Text1)) AS LOCAL BYTE AT STRPTR(text1)
    
       'preallocate characters
       text2  = SPACE$(LEN(text1))
    
       DIM ByteTextOut(1 TO LEN(text2)) AS LOCAL BYTE AT STRPTR(text2)
    
       'loop through all characters of the encrypted string
       FOR j = 1 TO LEN(text1)
          'get the current character of the key
          i = ByteKeyT(j MOD LEN(keyt)+1) - 31
    
          'get the numeric value of the current key character
          n = ByteTextIn(j) - i
          'shift the character of the text, rotate if necessary
          IF n < 32 THEN n = n + 95
    
          'insert to the deciphered string
          ByteTextOut(j) = n
    
       NEXT j
    
    END SUB
    
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    'eof
    [email protected]

    Comment


    • #3
      Petr, a great lesson for programmers about speed. On my PC the gain speed is 7x times. Using sentences like
      Code:
      DIM ByteTextIn(1 TO LEN(Text1)) AS LOCAL BYTE AT STRPTR(text1)
      is not necessary to use pointers and simplify a lot the code. Thanks.
      Jordi
      Last edited by Jordi Vallès; 16 Jul 2008, 07:11 AM.

      Comment

      Working...
      X