Vigenère шифрование в qbasic - PullRequest
       36

Vigenère шифрование в qbasic

2 голосов
/ 07 октября 2019

Как я могу написать шифрование Vigenère в Qbasic без использования массивов?
Я понимаю математику для шифрования сообщения:

Ca = Ma + Kb (mod 26)

И для расшифровки сообщения:

Ma = Ca – Kb (mod 26). 

Я борюсь с синтаксисом, так как я не нашел много информации в Интернете.

Ответы [ 2 ]

1 голос
/ 15 октября 2019

Вы можете легко решить эту проблему без использования каких-либо массивов.

Ниже приведено мое базовое (Q) решение BASIC.

Функция MID$ извлекает один символ из строки, аASC функция преобразует символ в его ASCII-код. Вычитание 65 дает число в диапазоне [0,25]. Зашифрованный номер превращается обратно в символ с помощью функции CHR$. В дальнейшем оператор MID$ используется для возврата зашифрованного символа обратно в строку.
Из-за разной длины сообщения и ключа шифрования необходима отдельная переменная итерации (j%) для многократного обхода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$

Приведенный выше фрагмент может обойтись без одного - 65 и одного + 65, но я оставил их для ясности.

Процесс дешифрования очень похож. 3 небольших изменения - это все, что требуется:

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$

Запуск обоих фрагментов подряд приводит к:

ENCRYPTION
GYKERDGKZV
ENCRYPTION


А как насчет версии кода, которая может работать с пробелами, знаками препинания и символами ударения?

Код очень похож и даже немного проще:

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$

Я не буду воспроизводить здесь какие-либо выходные данные, потому что это будет настоящая лава ...


Верны ли эти странные встроенные условия?

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

Рассмотрим эквивалентный простой код:

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

Если переменная a% больше 25, нам нужно вычесть 26.
Тем не менее форма (a% + 26 * (a% > 25)) использует добавление .

Это происходит потому, что условие TRUE оценивается как -1.

  • Если a% > 25 TRUE, мы получаем (a% + 26 * -1) -> a% - 26
  • Если a% > 25 ЛОЖЬ, мы получаем (a% + 26 * 0) -> a%
1 голос
/ 08 октября 2019

Вы можете просто получить значение ASCII символа в виде числа, а затем вычесть значение символа A. Вы получите число в диапазоне [0, 26). Тогда вы будете выполнять шифрование / дешифрование, как вы заявили. Чтобы вернуть действительное значение символа, затем поверните вспять и добавьте значение A. Это работает, потому что буквы английского алфавита (ABC) перечислены в порядке в ASCII.

Чтобы получить зашифрованный текст или открытый текст, просто переберите все символы в строке (возможно, после проверки, что это не таксодержат любые другие символы) и добавьте зашифрованный / расшифрованный символ к новой строке и, наконец, верните ее. Альт, никаких массивов, только строки, символы и числовые значения.

Вот и все, ребята.

...