Search code examples
c++alphabet

Implementing an alphabet in C++


I'm making a code for cipher that reads alphabet in it's binary code. Is there a way to implement custom alphabet (not using ASCII)? For example alphabet={a,b,c,d,e,...,z,],[,.,..., ,-} and for each character there's a number 0,1,...,63. So, the bijetion will be from element of alphabet to 6 bit number.

How to make this implementation using simple functions in C++? I tried to make a strings length 1 and corresponding number using if statements and then plug them into .txt file, but it didn't work out.

string str1, ..., str63;
string sometext;
str1 = 'a';

// ...

cin >> sometext;
int k;
k = sometext.length();
string res;
ofstream out;
out.open("cipher.txt");
for (int i = 0; i < k; i++) {
  res = sometext.substr(i, 1);
  if (res == str1) {
    res = '000000';
  }

  // ...

  if (res == str63) {
    res = '111111';
  }
  out << res;
}

Solution

  • I made a simple class Alphabet achieving your task. It uses std::unordered_map to store mapping between characters and binary representation, and uses this mapping to convert between those two representations. Also it computes binary representation. Class can be given any alphabet.

    For testing I do two conversions between char and binary and output results to console. If requested values are out of range then std::exception is thrown.

    Try it online!

    #include <string>
    #include <unordered_map>
    #include <cmath>
    #include <stdexcept>
    #include <iostream>
    
    class Alphabet {
    public:
        Alphabet(std::string const & _chars)
            : chars(_chars) {
            size_t num_bits = std::ceil(std::log(std::max(size_t(1), chars.size()))
                / std::log(2) - 1e-6);
            for (size_t i = 0; i < chars.size(); ++i) {
                std::string bin;
                for (ptrdiff_t j = num_bits - 1; j >= 0; --j)
                    bin += i & (1 << j) ? "1" : "0";
                c2b[chars[i]] = bin;
                b2c[bin] = chars[i];
            }
        }
        std::string ToBin(char c) const {
            auto it = c2b.find(c);
            if (it == c2b.end())
                throw std::runtime_error("Character '" +
                    std::string(1, c) + "' not in alphabet!");
            return it->second;
        }
        char ToChar(std::string const & bin) const {
            auto it = b2c.find(bin);
            if (it == b2c.end())
                throw std::runtime_error("Binary '" + bin + "' is out of range!");
            return it->second;
        }
        std::string const & Chars() const {
            return chars;
        }
    private:
        std::string chars;
        std::unordered_map<char, std::string> c2b;
        std::unordered_map<std::string, char> b2c;
    };
    
    int main() {
        try {
            Alphabet alph("abcdef{}123");
            std::cout << alph.ToBin('f') << std::endl;    
            std::cout << alph.ToChar("0011") << std::endl;
            std::cout << alph.Chars() << std::endl;
            return 0;
        } catch (std::exception const & ex) {
            std::cout << "Exception: " << ex.what() << std::endl;
            return -1;
        }
    }
    

    Output:

    0101
    d
    abcdef{}123