(C++) Encranger
January 25, 2018 · View on GitHub
(C++) Encranger



Encranger is one of my own cryptography classes.
Encranger is used in, among others:
Technical facts
./CppEncranger/CppEncranger.pri
INCLUDEPATH += \ ../../Classes/CppEncranger SOURCES += \ ../../Classes/CppEncranger/encranger.cpp HEADERS += \ ../../Classes/CppEncranger/encranger.h OTHER_FILES += \ ../../Classes/CppEncranger/Licence.txt
./CppEncranger/encranger.h
//--------------------------------------------------------------------------- /* Encranger, encryption and de-encryption class Copyright 2010-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- // From http://www.richelbilderbeek.nl/ToolMultiEncranger.htm //--------------------------------------------------------------------------- #ifndef ENCRANGER_H #define ENCRANGER_H #include <string> #include <vector> namespace ribi { //Encranger stands for 'ENCryption by RAndom Number GEneratoR' struct Encranger { Encranger(const int key) noexcept; std::string Encrypt(std::string s) const noexcept; std::string Deencrypt(std::string s) const noexcept; static std::string GetVersion() noexcept; static std::vector<std::string> GetVersionHistory() noexcept; private: const std::vector<char> m_characters; const std::vector<int> m_table; ///The unsigned int is the size of 'm_characters' std::vector<int> CreateTable(const int key, const unsigned int sz) const noexcept; static std::vector<int> CreateTestKeys() noexcept; static std::vector<char> CreateCharacters() noexcept; char Encrypt(const char c, const int d) const noexcept; char Deencrypt(const char c, const int d) const noexcept; int GetIndex(const char c) const noexcept; #ifndef NDEBUG static void Test() noexcept; #endif }; } //~namespace ribi #endif // ENCRANGER_H
./CppEncranger/encranger.cpp
//--------------------------------------------------------------------------- /* Encranger, encryption and de-encryption class Copyright 2010-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- // From http://www.richelbilderbeek.nl/ToolMultiEncranger.htm //--------------------------------------------------------------------------- #include "encranger.h" #include <algorithm> #include <cassert> #include <functional> #include <iostream> #include <stdexcept> #include <numeric> #include <vector> #include "testtimer.h" #include "trace.h" #include "loopreader.h" ribi::Encranger::Encranger(const int key) noexcept : m_characters(CreateCharacters()), m_table(CreateTable(key,CreateCharacters().size())) { #ifndef NDEBUG Test(); #endif } std::vector<int> ribi::Encranger::CreateTestKeys() noexcept { std::vector<int> v; int x=1; for (int i=0; i!=16; ++i) { v.push_back(x); x *= 2; } return v; } std::string ribi::Encranger::Encrypt(std::string s) const noexcept { typedef std::string::iterator StringIterator; typedef std::vector<int>::const_iterator LoopReaderIteratorType; LoopReader<LoopReaderIteratorType> table_reader(m_table.begin(), m_table.end()); const StringIterator j = s.end(); for (StringIterator i = s.begin(); i!=j; ++i, table_reader.Next()) { *i = Encrypt(*i,*table_reader.Read()); } return s; } std::string ribi::Encranger::Deencrypt(std::string s) const noexcept { typedef std::string::iterator StringIterator; LoopReader<std::vector<int>::const_iterator> table_reader(m_table.begin(), m_table.end()); const StringIterator j = s.end(); for (StringIterator i = s.begin(); i!=j; ++i, table_reader.Next()) { *i = Deencrypt(*i,*table_reader.Read()); } return s; } char ribi::Encranger::Encrypt(const char c, const int d) const noexcept { const int i = GetIndex(c); const int n_chars = static_cast<int>(m_characters.size()); const int i_new = (i + d) % n_chars; assert(i_new >= 0); assert(i_new < static_cast<int>(m_characters.size())); return m_characters[i_new]; } char ribi::Encranger::Deencrypt(const char c, const int d) const noexcept { const int i = GetIndex(c); const int n_chars = static_cast<int>(m_characters.size()); const int i_new = (i - d + n_chars) % n_chars; assert(i_new >= 0); assert(i_new < static_cast<int>(m_characters.size())); return m_characters[i_new]; } int ribi::Encranger::GetIndex(const char c) const noexcept { if (c == '\t' || c == '\n') return GetIndex(' '); const std::vector<char>::const_iterator i = std::find(m_characters.begin(), m_characters.end(), c); assert(i!=m_characters.end()); return i - m_characters.begin(); } std::vector<int> ribi::Encranger::CreateTable(const int key, const unsigned int sz) const noexcept { assert(sz != 0 && "Supplied table must not be of size zero"); std::vector<int> v(sz); std::iota(v.begin(),v.end(),0); //The key is the seed std::srand(key); //Shuffle std::random_shuffle(std::begin(v),std::end(v)); return v; } std::vector<char> ribi::Encranger::CreateCharacters() noexcept { std::vector<char> v; //Uppercase v.push_back('A'); v.push_back('B'); v.push_back('C'); v.push_back('D'); v.push_back('E'); v.push_back('F'); v.push_back('G'); v.push_back('H'); v.push_back('I'); v.push_back('J'); v.push_back('K'); v.push_back('L'); v.push_back('M'); v.push_back('N'); v.push_back('O'); v.push_back('P'); v.push_back('Q'); v.push_back('R'); v.push_back('S'); v.push_back('T'); v.push_back('U'); v.push_back('V'); v.push_back('W'); v.push_back('X'); v.push_back('Y'); v.push_back('Z'); //Lowercase v.push_back('a'); v.push_back('b'); v.push_back('c'); v.push_back('d'); v.push_back('e'); v.push_back('f'); v.push_back('g'); v.push_back('h'); v.push_back('i'); v.push_back('j'); v.push_back('k'); v.push_back('l'); v.push_back('m'); v.push_back('n'); v.push_back('o'); v.push_back('p'); v.push_back('q'); v.push_back('r'); v.push_back('s'); v.push_back('t'); v.push_back('u'); v.push_back('v'); v.push_back('w'); v.push_back('x'); v.push_back('y'); v.push_back('z'); //Digits v.push_back('0'); v.push_back('1'); v.push_back('2'); v.push_back('3'); v.push_back('4'); v.push_back('5'); v.push_back('6'); v.push_back('7'); v.push_back('8'); v.push_back('9'); //Above digits v.push_back('!'); v.push_back('@'); v.push_back('#'); v.push_back('$'); v.push_back('%'); v.push_back('^'); v.push_back('&'); v.push_back('*'); v.push_back('('); v.push_back(')'); //Other interpunction v.push_back('~'); v.push_back('`'); v.push_back('-'); v.push_back('_'); v.push_back('='); v.push_back('+'); v.push_back('['); v.push_back(']'); v.push_back('{'); v.push_back('}'); v.push_back(';'); v.push_back(':'); v.push_back('\''); v.push_back('\"'); v.push_back('<'); v.push_back('>'); v.push_back(','); v.push_back('.'); v.push_back('/'); v.push_back('?'); v.push_back('\\'); v.push_back('|'); v.push_back(' '); return v; } std::string ribi::Encranger::GetVersion() noexcept { return "1.3"; } std::vector<std::string> ribi::Encranger::GetVersionHistory() noexcept { return { "2010-01-05: version 1.0: initial version", "2011-01-12: version 1.1: added version info", "2014-04-01: version 1.2: replaced use of custom Increase class by std::iota", "2014-07-21: version 1.3: rigid testing" }; } #ifndef NDEBUG void ribi::Encranger::Test() noexcept { { static bool is_tested{false}; if (is_tested) return; is_tested = true; } const TestTimer test_timer(__func__,__FILE__,1.0); //Test Increase { const std::size_t sz { 5 }; std::vector<int> v(sz); //std::for_each(v.begin(), v.end(), Increase() ); std::iota(v.begin(),v.end(),0); for (std::size_t i=0; i!=sz; ++i) { assert( v[i] == static_cast<int>(i) ); } } { const std::vector<std::string> v { "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", "a cde ghijklm opqrstuvwxyzabc efghijklmnopqrstuvwxyzabcdefghi klmnopqrstuvwxyz", "a", " a", "a ", " a ", " a " }; for (const std::string& s: v) { for (const int key: CreateTestKeys()) { const Encranger e(key); assert(e.Deencrypt(e.Encrypt(s)) == s); //Test encryption with real, decryption with faker const Encranger faker(key + 1); if (faker.Deencrypt(e.Encrypt(s)) == s) { TRACE("ERROR"); TRACE(key); TRACE(s); TRACE("BREAK"); } assert(faker.Deencrypt(e.Encrypt(s)) != s); } } } } #endif