Ответ в теме: Реализация шифра Скитала на С++

      Комментарии к записи Ответ в теме: Реализация шифра Скитала на С++ отключены

Главная Форумы Программирование Программирование на С++ Реализация шифра Скитала на С++ Ответ в теме: Реализация шифра Скитала на С++

#3552

Daniil159x
Участник

Я представлю немного другую реализацию шифра. И поговорим про ключи.

Немножко теории:

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

Суть в том, что искомая строка уже является «матрицей». Которая реализована последовательно, то есть строки таблицы идут друг за другом.

Выведем формулу для получения [i][j] индекса матрицы из обычного массива.

  1. i — это порядковый номер строки(счёт идёт с 0), j — это номер столбца или номер элемента в i строке.
  2. строки имеют одинаковую длину(далее переменная width).

Рассуждаем: по 2 пункту одна строка имеет row элементов, две строки — 2*width, три — 3*width и т д.
Нам нужно найти i строку и j символ в ней. Значит нам надо пропустить i*width элементов и взять j символ.
Формула такова: index = i*width + j

Теперь будем читать и сразу выводить «матрицу».
s — искомая строка

for(size_t j = 0; j < widht; ++j){
    for(size_t i = 0; i < heigth; ++i){
    	std::cout << ((i*widht + j < s.size()) ? s[i*widht + j] : '*');
    }
}

Для чего нам условие i*widht + j < s.size() ?
Посмотрим на пример из вики.

Искомая строка: НАС_АТАКУЮТ — имеет длину 11, таблица(4x3) имеет 12 ячеек, значит, когда циклы запросят [2][3] индекс, программа выйдет за границы строки.

| Н | А | С |__ |
| А | Т | А | К |
| У | Ю | Т | * |

Теперь чуть-чуть о ключах.
Обычно берут высоту, а длину вычисляют. Для этого есть формула n = [(k-1)/m]+1, где n — количество столбцов, k — длина сообщения, m — количество строк.
Эта же формула действует и в обратном направлении.
Если взять m как количество столбцов, то n будет количество строк.

На этом всё. В другой раз напишу, как дешифровать с помощью такого же метода.

Исходный код программы полностью:

    
#include <iostream>
#include <string>

int main() {
    std::string s;
    size_t heigth, widht;
    
    std::getline(std::cin, s);
    std::cin >> heigth;
    widht = (s.size() - 1) / heigth + 1;
     
    for(size_t j = 0; j < widht; ++j){
        for(size_t i = 0; i < heigth; ++i){
            std::cout << ((i*widht + j < s.size()) ? s[i*widht + j] : '*');
        }
    }
     
    std::cout << std::endl;
     
    return 0;
}