Skip to main content
deleted 113 characters in body
Source Link
Roland Illig
  • 21.4k
  • 2
  • 34
  • 83

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();
}

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 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
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";

        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) {
            unsigned char d0 = (cc0bits << 1) | ((vv0bits & 0x10) >> 4);
            out << d0;
            if (cc1bits == 128) {
                if (text.substr(i) == "??")
                    break;
                throw "invalid encoded data (padding)";
            }

            unsigned char d1 = ((vv0bits & 0x0F) << 4) | ((cc1bits & 0x78) >> 3);
            out << d1;
            if (vv1bits == 32) {
                if (text.substr(i) == "?")
                    break;
                throw "invalid encoded data (padding)";
            }

            unsigned char d2 = ((cc1bits & 0x07) << 5) | (vv1bits & 0x1F);
            out << d2;
        }
    }

    return out.str();
}

For decoding a string of consonants and vowels into the original data, 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 (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) != "??")
                throw "invalid encoded data (padding)";
            break;
        }
        unsigned char d1 = ((vv0bits & 0x0F) << 4) | ((cc1bits & 0x78) >> 3);
        out << d1;
 
        if (vv1bits == 32) {
            if (text.substr(i) != "?")
                throw "invalid encoded data (padding)";
            break;
        }
        unsigned char d2 = ((cc1bits & 0x07) << 5) | (vv1bits & 0x1F);
        out << d2;
    }

    return out.str();
}
deleted 113 characters in body
Source Link
Roland Illig
  • 21.4k
  • 2
  • 34
  • 83
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";

        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) {
            unsigned char d0 = (cc0bits << 1) | ((vv0bits & 0x10) >> 4);
            out << d0;
            if (cc1bits !=== 128) {
                unsigned char d1 =if (text.substr(vv0bits & 0x0Fi) <<== 4"??") 
 | ((cc1bits & 0x78) >> 3);
              break;
  out << d1;
             throw "invalid encoded ifdata (vv1bitspadding)";
 != 32) {
         }

            unsigned char d2d1 = ((cc1bitsvv0bits & 0x070x0F) << 54) | (vv1bits(cc1bits & 0x1F0x78);
       >> 3);
            out << d2;
                }d1;
             if (vv1bits == else32) {
                    if (text.substr(i) == "?")
                        break;
                    throw "invalid encoded data (padding)";
                }
            }
            else {
             unsigned char d2 if= (text.substr(i)cc1bits ==& "??"0x07)
               << 5) | (vv1bits & break;0x1F);
                throw "invalid encoded data (padding)";
          out << }d2;
        }
    }

    return out.str();
}
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";

        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) {
            unsigned char d0 = (cc0bits << 1) | ((vv0bits & 0x10) >> 4);
            out << d0;
            if (cc1bits != 128) {
                unsigned char d1 = ((vv0bits & 0x0F) << 4) | ((cc1bits & 0x78) >> 3);
                out << d1;
                if (vv1bits != 32) {
                    unsigned char d2 = ((cc1bits & 0x07) << 5) | (vv1bits & 0x1F);
                    out << d2;
                }
                else {
                    if (text.substr(i) == "?")
                        break;
                    throw "invalid encoded data (padding)";
                }
            }
            else {
                if (text.substr(i) == "??")
                    break;
                throw "invalid encoded data (padding)";
            }
        }
    }

    return out.str();
}
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";

        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) {
            unsigned char d0 = (cc0bits << 1) | ((vv0bits & 0x10) >> 4);
            out << d0;
            if (cc1bits == 128) {
                if (text.substr(i) == "??") 
                    break;
                throw "invalid encoded data (padding)";
            }

            unsigned char d1 = ((vv0bits & 0x0F) << 4) | ((cc1bits & 0x78) >> 3);
            out << d1;
            if (vv1bits == 32) {
                if (text.substr(i) == "?")
                    break;
                throw "invalid encoded data (padding)";
            }

            unsigned char d2 = ((cc1bits & 0x07) << 5) | (vv1bits & 0x1F);
            out << d2;
        }
    }

    return out.str();
}
added 660 characters in body
Source Link
Roland Illig
  • 21.4k
  • 2
  • 34
  • 83

Your is_vowel function can be shortened a bit.

bool is_vowel(char x) { bool o = false; std::size_t i; for (i = 0; i < vow_l.size(); i++) { if (x == vow_l[i]) { o = true; break; } } return o; }

bool is_vowel(char x) { std::size_t i; for (i = 0; i < vow_l.size(); i++) { if (x == vow_l[i]) { return true; } } return false; }

bool is_vowel(char x) { for (std::size_t i = 0; i < vow_l.size(); i++) { if (x == vow_l[i]) { return true; } } return false; }

bool is_vowel(char x) { return vow_l.find(x) != std::string::npos; }

Instead of using break and a return value, it is often simpler to just return value, e.g. in string_find.


Your is_vowel function can be shortened a bit.

bool is_vowel(char x) { bool o = false; std::size_t i; for (i = 0; i < vow_l.size(); i++) { if (x == vow_l[i]) { o = true; break; } } return o; }

bool is_vowel(char x) { std::size_t i; for (i = 0; i < vow_l.size(); i++) { if (x == vow_l[i]) { return true; } } return false; }

bool is_vowel(char x) { for (std::size_t i = 0; i < vow_l.size(); i++) { if (x == vow_l[i]) { return true; } } return false; }

bool is_vowel(char x) { return vow_l.find(x) != std::string::npos; }

Instead of using break and a return value, it is often simpler to just return value, e.g. in string_find.

Source Link
Roland Illig
  • 21.4k
  • 2
  • 34
  • 83
Loading