首页 > 解决方案 > qbasic 中的 Vigenère 加密

问题描述

如何在不使用数组的情况下在 Qbasic 中编写 Vigenère 加密?
我了解加密消息的数学原理:

Ca = Ma + Kb (mod 26)

并解密消息:

Ma = Ca – Kb (mod 26). 

我在语法上苦苦挣扎,因为我在网上找不到太多信息。

标签: encryptionqbasic

解决方案


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.

  • If a% > 25 is TRUE we get (a% + 26 * -1) -> a% - 26
  • If a% > 25 is FALSE we get (a% + 26 * 0) -> a%

推荐阅读