Created
July 12, 2021 17:32
-
-
Save foxyseta/bbdc3a54339b5d2fc253b117fccf27c1 to your computer and use it in GitHub Desktop.
Minimal transposition cipher implementation in C++.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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