encryptionqbasic

Vigenère encryption in qbasic


How can I write a Vigenère encryption in Qbasic without the use of arrays?
I understand the math to encrypt a message:

Ca = Ma + Kb (mod 26)

And to decrypt a message:

Ma = Ca – Kb (mod 26). 

I'm struggling with the syntax as I haven't found much information online.


Solution

  • You can solve this easily without using any arrays.

    Below is my all-(Q)BASIC solution.

    The MID$ function extracts one character from a string, and the ASC function converts the character into its ASCII code. Subtracting 65 produces a number in the range [0,25]. The encrypted number is turned back into a character using the CHR$ function. Hereafter the MID$ statement is used to put the encrypted character back in the string.
    Because of the different lengths between the message and the encryption key, a separate iteration variable (j%) is needed to repeatedly walk through the key string.

    msg$ = "ENCRYPTION"
    PRINT msg$
    key$ = "CLINTON"
    k% = LEN(key$)
    j% = 1
    FOR i% = 1 TO LEN(msg$)
      a% = (ASC(MID$(msg$, i%, 1)) - 65) + (ASC(MID$(key$, j%, 1)) -65)
      MID$(msg$, i%) = CHR$(65 + a% + 26 * (a% > 25))
      j% = j% + 1 + k% * (j% = k%)
    NEXT i%
    PRINT msg$
    

    The above snippet could do without one - 65 and one + 65, but I've left these in for clarity.

    The decryption process is quite similar. 3 little changes are all that it takes:

    j% = 1
    FOR i% = 1 TO LEN(msg$)
      a% = (ASC(MID$(msg$, i%, 1)) - 65) - (ASC(MID$(key$, j%, 1)) -65)
      MID$(msg$, i%) = CHR$(65 + a% - 26 * (a% < 0))
      j% = j% + 1 + k% * (j% = k%)
    NEXT i%
    PRINT msg$
    

    Running both snippets in a row produces:

    ENCRYPTION
    GYKERDGKZV
    ENCRYPTION


    What about a version of the code that can deal with spaces, punctuation marks, and accented characters?

    The code is very similar and even a bit simpler:

    msg$ = "This is any text that needs encrypting. So sayeth Sep Roland!"
    PRINT msg$
    key$ = "Blaise de Vigenère"
    k% = LEN(key$)
    j% = 1
    FOR i% = 1 TO LEN(msg$)
      a% = ASC(MID$(msg$, i%, 1)) + ASC(MID$(key$, j%, 1))
      MID$(msg$, i%) = CHR$(a% + 256 * (a% > 255))
      j% = j% + 1 + k% * (j% = k%)
    NEXT i%
    PRINT msg$
    
    j% = 1
    FOR i% = 1 TO LEN(msg$)
      a% = ASC(MID$(msg$, i%, 1)) - ASC(MID$(key$, j%, 1))
      MID$(msg$, i%) = CHR$(a% - 256 * (a% < 0))
      j% = j% + 1 + k% * (j% = k%)
    NEXT i%
    PRINT msg$
    

    I will not reproduce any output here because that would be a real pita...


    Are these strange embedded conditions correct?

    (a% + 26 * (a% > 25))

    Consider the equivalent simple code:

    IF a% > 25 THEN
      a% = a% - 26
    ENDIF
    

    If the a% variable is greater than 25, we need to subtract 26.
    Nonetheless the (a% + 26 * (a% > 25)) form uses addition.

    This so happens because a TRUE condition evaluates to -1.