This is a binary-to-text encoder that is based on Base64, but it works by converting data into an almost pronounceable string (consonant-vowel-consonant-vowel for each 3 bytes). Any improvements, suggestions, etc. are welcome.bitspeak.hpp#ifndef BITSPEAK_HPP#define BITSPEAK_HPP/*Encoding:     ******** ******** ********     CCCCCCCV VVVVCCCC CCCVVVVV-CCCCCCC ---VVVVV -CCCCCCC ---VVVVVC: ConsonantV: VowelDecoding:-******* ---***** -******* ---*****-xxxxxxx ---xyyyy -yyyyzzz ---zzzzz     xxxxxxxx yyyyyyyy zzzzzzzz*/#include <iostream>#include <cstdlib>#include <cstdint>#include <cstring>#include <string>#include <sstream>#include <vector>namespace bitspeak{static const std::string vows[32] = {a,e,i,o,u,w,y,ae,ai,ao,au,aw,ay,ea,ee,ei,eo,eu,ey,ia,io,iu,oa,oi,ou,ow,oy,ui,uo,uy,we,wi};static const std::string cons[128] = {b,c,d,f,g,h,j,k,l,m,n,p,q,r,s,t,v,x,z,bc,bl,br,bs,ch,chs,cht,ck,cl,cr,cs,ct,fl,fr,fs,ft,gl,gm,gr,gs,gz,hd,hf,hr,hs,ht,hv,jr,js,jt,kl,kr,kt,lb,lc,ld,lg,lm,ln,lp,ls,lt,lv,mb,mn,mp,mr,nd,nk,nm,np,ns,nt,nv,nz,pl,pr,ps,pt,pz,rb,rc,rch,rd,rf,rg,rk,rl,rm,rn,rp,rr,rs,rt,rv,rz,sb,sc,sch,sd,sf,sh,sl,sm,sn,sp,sq,sr,st,sth,str,sv,sz,tch,th,tl,tn,tr,ts,vl,vr,vs,vz,xc,xz,zd,zl,zp,zt};static const std::string vow_l = aeiouwy;static const std::string con_l = bcdfghjklmnpqrstvxz;std::vector<std::string> split(const char* str,char delim){    std::stringstream ss;    std::string str1 = str;    std::vector<std::string> splitted;    std::string rfs;    while (str1[0] == delim) { str1.erase(0,1); }    int se = str1.length();    while (str1[se-1] == delim) { str1.erase(se-1,se); se = str1.length(); }    for (int i=0;i<str1.length()-1;i++)    {        if (str1[i] == delim && str1[i+1] == delim)            continue;        else            rfs += str1[i];    }    rfs += str1[str1.length()-1];    for (int i=0;i<rfs.length()+1;i++)    {        if (rfs[i] != delim && i != rfs.length())            ss << rfs[i];        else        {            splitted.push_back(ss.str());            ss.str(std::string());        }    }    return splitted;}void ca3_to_ca4(uint8_t _a3[3],uint8_t _a4[4]){    _a4[0] = (_a3[0]&0xFE) >> 1;    _a4[1] = ((_a3[0]&0x01) << 4) | ((_a3[1]&0xF0) >> 4);    _a4[2] = ((_a3[1]&0x0F) << 3) | ((_a3[2]&0xE0) >> 5);    _a4[3] = _a3[2]&0x1F;}void ca4_to_ca3(uint8_t _a4[4],uint8_t _a3[3]){    _a3[0] = ((_a4[0]&0x7F) << 1) | ((_a4[1]&0x10) >> 4);    _a3[1] = ((_a4[1]&0x0F) << 4) | ((_a4[2]&0x78) >> 3);    _a3[2] = ((_a4[2]&0x07) << 5) | (_a4[3]&0x1F);}bool is_vowel(char x) { bool o = false; int i; for (i=0;i<vow_l.size();i++) { if (x == vow_l[i]) { o = true; break; } } return o; }bool is_consonant(char x) { bool o = false; int i; for (i=0;i<con_l.size();i++) { if (x == con_l[i]) { o = true; break; } } return o; }uint32_t string_find(const std::string *arr,std::string x,uint32_t size){    uint32_t idx = -1, i = 0;    for (i=0;i<size;i++)    {        if (x == arr[i])        {            idx = i;            break;        }    }    return idx;}void encode(uint8_t *data,uint32_t length,std::string& out){    uint32_t i = 0, j = 0;    uint8_t ca3[3];    uint8_t ca4[4];    while (length--)    {        ca3[i++] = *(data++);        if (i == 3)        {            ca3_to_ca4(ca3,ca4);            // Put consonants and vowels (form is CVCV for each 3 bytes of data)            for (i=0;i<4;i++)            {                if (i == 0) out += cons[ca4[0]];                if (i == 1) out += vows[ca4[1]];                if (i == 2) out += cons[ca4[2]];                if (i == 3) out += vows[ca4[3]];            }            i = 0;        }    }    if (i)    {        for (j=i;j<3;j++)            ca3[j] = '\0';        ca3_to_ca4(ca3,ca4);        for (j=0;j<(i+1);j++)        {            if (j == 0) out += cons[ca4[0]];            if (j == 1) out += vows[ca4[1]];            if (j == 2) out += cons[ca4[2]];            if (j == 3) out += vows[ca4[3]];        }        // Put padding        while ((i++ < 3))            out += ?;    }}void decode(const char *data,uint32_t length,std::string& out){    uint32_t i = 0, j = 0, si = 0;    uint8_t ca3[3];    uint8_t ca4[4];    std::string sa4[4];    uint32_t slen = length;    std::vector<std::string> vow_v; // Vowels    std::vector<std::string> con_v; // Consonants    std::vector<std::string> all_v; // All data to decode    std::string vow_tmp, con_tmp, pad_tmp; // Placeholders for consonants, vowels and padding    uint32_t padc = 0;    while ((i < slen))    {        if (is_consonant(data[i]))        {            con_tmp += data[i];            vow_tmp += '*'; pad_tmp += '*';        }        if (is_vowel(data[i]))        {            vow_tmp += data[i];            con_tmp += '*'; pad_tmp += '*';        }        if (data[i] == '?')        {            pad_tmp += data[i];            con_tmp += '*'; vow_tmp += '*';            padc++;        }        i++;    }    // Split    vow_v = split(vow_tmp.c_str(),'*');    con_v = split(con_tmp.c_str(),'*');    // Put consonants and vowels (form is CVCV for each 3 bytes of data)    uint32_t np = vow_v.size()+con_v.size();    for (i=0;i<np;i++)    {        if (i%2 == 0) all_v.push_back(con_v[i/2]);        if (i%2 == 1) all_v.push_back(vow_v[i/2]);    }    // Put padding    for (i=0;i<padc;i++)        all_v.push_back(?);    uint32_t vlen = all_v.size();    i = 0;    while (vlen-- && (all_v[si] != ?))    {        // Find which position is the one that corresponds to cons. and vow.        if (si%2 == 0) ca4[i++] = (uint8_t)string_find(cons,con_v[si/2],128);        if (si%2 == 1) ca4[i++] = (uint8_t)string_find(vows,vow_v[si/2], 32);        si++;        if (i == 4)        {            ca4_to_ca3(ca4,ca3);            for (i=0;i<3;i++)            {                if (i == 0) out += ca3[0];                if (i == 1) out += ca3[1];                if (i == 2) out += ca3[2];            }            i = 0;        }    }    if (i)    {        for (j=i;j<4;j++)            ca4[j] = 0;        ca4_to_ca3(ca4,ca3);        for (j=0;j<(i-1);j++)        {            if (j == 0) out += ca3[0];            if (j == 1) out += ca3[1];            if (j == 2) out += ca3[2];        }    }}} // end of bitspeak namespace#endifbitspeak_test.cpp#include <iostream>#include <cstdlib>#include <cstring>#include <string>#include bitspeak.hppusing namespace std;int main(int argc,char **argv){    string tests[4] = {        Technological progress is like an axe in the hands of a pathological criminal.,        Bitspeak test,        123456789abcdef,         ((( d(O_o)b )))     };    cout << .....--------============= Bitspeak test =============--------.....\n;    for (int i=0;i<4;i++)    {        string encoded, decoded;        cout << Test string  << (i+1) << :  << tests[i] << \n;        bitspeak::encode(            (uint8_t*)tests[i].c_str(),            tests[i].length(),            encoded        );        cout << Encoded:        << encoded << \n;        bitspeak::decode(            encoded.c_str(),            encoded.length(),            decoded        );        cout << Decoded:        << decoded << \n\n;    }}Here is the output of the test program:.....--------============= Bitspeak test =============--------.....Test string 1: Technological progress is like an axe in the hands of a pathological criminal.Encoded:       hryhsolbytneildyxzaelboacleldifeolnyxzaelnyhsialneyfaolneyfaylboarswvypeevypoukreyfaolgifiolbyhfalbypeekraechtalgoaklajteyfeojtoiglailgoasfeiktoaprojtoaschakloibcaoldoapreejtoascheeDecoded:       Technological progress is like an axe in the hands of a pathological criminal.Test string 2: Bitspeak testEncoded:       fsypriolnoifwjtoarpalpyhsialpa??Decoded:       Bitspeak testTest string 3: 123456789abcdefEncoded:       chsiaxiackohfoacliamrowjtoabcokryhsyDecoded:       123456789abcdefTest string 4:  ((( d(O_o)b ))) Encoded:       vimraiblifubluxcwilgeyprivinzaobleyb?Decoded:        ((( d(O_o)b )))
Pronounceable binary-to-text encoding
c++;converting
Your test program should not just print the values for manual inspection, it should check that the conversion's results are the expected ones, and otherwise fail. For more information on this subject, search for unit tests.Do not use identifiers starting with an underscore (e.g. _a3). Such identifiers are reserved for the system. Whenever you use them, your code looks like it were poking around in the innards of the system.Don't use using namespace std (just search for this on Stack Overflow).Bug: when a string consists of only delimiters, your code accesses str[-1], which leads to undefined behavior.