Skip to content

Instantly share code, notes, and snippets.

@foxyseta
Created July 12, 2021 17:32
Show Gist options
  • Save foxyseta/bbdc3a54339b5d2fc253b117fccf27c1 to your computer and use it in GitHub Desktop.
Save foxyseta/bbdc3a54339b5d2fc253b117fccf27c1 to your computer and use it in GitHub Desktop.
Minimal transposition cipher implementation in C++.
/*
es. 07 - transposition_cipher.cpp
Creare una classe Codice con attributi due stringhe (l'originale e la
trasformata). Creare un programma di trasformazione che prenda dal
main una stringa e la codifichi e decodifichi col cifrario A
TRASPOSIZIONE (libro pag. 66). Scegliere i metodi a piacere,
considerando che da una stringa iniziale si debba potere codificare
(metodo CODIFICA) e decodificare (metodo DECODIFICA).
Volpe Stefano (5Bsa)
11/02/2020
C++11
*/
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Codice {
public:
Codice() = delete; // chiave necessaria
Codice(Codice&&) = default; // spostamento
Codice& operator=(Codice&&) = default;
Codice(const Codice&) = default; // copia
Codice& operator=(const Codice&) = default;
~Codice() = default;
Codice(string chiave, char tappabuchi = '*');
Codice& operator=(string chiave);
string chiave() const;
char tappabuchi() const;
string codifica(string chiaro) const;
string decodifica(string cifrato) const;
private:
string key; // chiave del cifrario
// permutazioni indici delle colonne
vector<size_t> perm_cod, perm_dec;
char fill_char; // riempie li spazi vuoti del cifrario
size_t righe(string messaggio) const;
};
int main() {
cout << "Inserisci chiave: ";
string ch;
cin >> ch;
Codice co{ch};
cout << "Inserisci chiaro: ";
cin >> ch;
string ci;
cout << ch << " -> " << (ci = co.codifica(ch));
cout << " -> " << co.decodifica(ci) << "\n";
return 0;
}
Codice::Codice(string chiave, char tappabuchi)
:key{chiave}, fill_char{tappabuchi} {
// calcolo perm_dec
perm_dec.resize(key.size());
for (size_t i{0}; i < perm_dec.size(); ++i)
perm_dec.at(i) = i;
auto compara_indici = [this] (size_t a, size_t b) {
return key.at(a) < key.at(b);
};
sort(perm_dec.begin(), perm_dec.end(), compara_indici);
// calcolo perm_cod
perm_cod.resize(key.size());
for (size_t i{0}; i < perm_cod.size(); ++i)
perm_cod.at(perm_dec.at(i)) = i;
}
Codice& Codice::operator=(string chiave) {
*this = Codice(chiave);
return *this;
}
string Codice::chiave() const {
return key;
}
char Codice::tappabuchi() const {
return fill_char;
}
string Codice::codifica(string chiaro) const {
string res;
res.resize(chiaro.size() + key.size() - (chiaro.size() % key.size()));
const size_t lines{righe(chiaro)}; // righe
for (size_t i{0}; i < res.size(); ++i) {
const size_t j{(i % lines) * key.size() + perm_cod.at(i / lines)};
res.at(i) = j < chiaro.size() ? chiaro.at(j) : fill_char;
}
return res;
}
string Codice::decodifica(string cifrato) const {
string res;
res.resize(cifrato.size());
const size_t lines{righe(cifrato)}; // righe
for (size_t i{0}; i < res.size(); ++i)
res.at(i) = cifrato.at(
(perm_dec.at(i % key.size()) % key.size())
* lines + i / key.size()
);
return res;
}
size_t Codice::righe(string messaggio) const {
return (messaggio.size() + key.size() - 1) / key.size();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment