For decoding a string of consonants and vowels into the original data, the idiomatic C++ code does not copy much data around. Instead, it uses indexes or iterators into the strings, which are only pointers that can be efficiently passed around.
- find a sequence of consonants
- find a sequence of vowels
- find a sequence of consonants
- find a sequence of vowels
- map the above sequences to indices
- bitshift the indices around to produce the original data
- repeat until the end of the encoded string
std::string decode(const std::string &text)
{
std::size_t i = 0;
std::size_t len = text.length();
std::ostringstream out;
while (i < len) {
auto cc0start = i;
while (i < len && con_l.find(text[i]) != std::string::npos)
i++;
auto vv0start = i;
while (i < len && vow_l.find(text[i]) != std::string::npos)
i++;
auto cc1start = i;
while (i < len && con_l.find(text[i]) != std::string::npos)
i++;
auto vv1start = i;
while (i < len && vow_l.find(text[i]) != std::string::npos)
i++;
if (i == cc0start)
throw "invalid encoded data";data (neither consonant nor vowel)";
auto cc0 = text.substr(cc0start, vv0start - cc0start);
auto vv0 = text.substr(vv0start, cc1start - vv0start);
auto cc1 = text.substr(cc1start, vv1start - cc1start);
auto vv1 = text.substr(vv1start, i - vv1start);
auto cons_end = cons + 128;
auto vows_end = vows + 32;
auto cc0bits = std::find(cons, cons_end, cc0) - cons;
auto vv0bits = std::find(vows, vows_end, vv0) - vows;
auto cc1bits = std::find(cons, cons_end, cc1) - cons;
auto vv1bits = std::find(vows, vows_end, vv1) - vows;
if (cc0bits !=== 128 &&|| vv0bits !=== 32) {
throw "invalid encoded data (unknown letter combination)";
unsigned char d0 = (cc0bits << 1) | ((vv0bits & 0x10) >> 4);
out << d0;
if (cc1bits == 128) {
if (text.substr(i) ==!= "??")
break;
throw "invalid encoded data (padding)";
}
break;
}
unsigned char d1 = ((vv0bits & 0x0F) << 4) | ((cc1bits & 0x78) >> 3);
out << d1;
if (vv1bits == 32) {
if (text.substr(i) ==!= "?")
break;
throw "invalid encoded data (padding)";
}
break;
}
unsigned char d2 = ((cc1bits & 0x07) << 5) | (vv1bits & 0x1F);
out << d2;
}
}
return out.str();
}