Skip to main content
added 108 characters in body
Source Link
esote
  • 3.8k
  • 2
  • 23
  • 44
#include <iostream>
#include <vector>
#include <sstream>
#include <iterator>
#include <algorithm>

std::string getString();
std::vector<std::string> tokenize(const std::string & str);
std::vector<int> getPattern();

int main(){
    std::string input;
    std::vector<std::string> words;
    std::vector<int> pattern;
    do{
        if(words.size() != pattern.size()){
            std::cout << "\nError: Number of words must be equal to number of integers in pattern.";
        }
        input = getString();
        words = tokenize(input);
        pattern = getPattern();
    } while(words.size() != pattern.size());

    for(int i = 0; i < words.size(); ++i){
        if(words[i].length() > pattern[i]){
            std::string str = words[i];
            std::cout << str[pattern[i]];
        }
    }

    std::cout << '\n';
    return 0;
}

std::string getString(){
    std::cout << "Seperate words with spaces.\nInput string: ";
    std::string input;
    std::getline(std::cin, input);
    return input;
}

std::vector<std::string> tokenize(const std::string & str){
    std::stringstream ss(str);
    std::istream_iterator<std::string> begin(ss);
    std::istream_iterator<std::string> end;
    std::vector<std::string> words(begin, end);
    return words;
}

std::vector<int> getPattern(){
    std::string pattern;
    std::vector<int> intTokenizedPattern;
    bool validPattern;
    do{
        std::cout << "Seperate positive integers with spaces: ";
        std::getline(std::cin, pattern);
        std::vector<std::string> tokenizedPattern = tokenize(pattern);
        try{
            std::transform(tokenizedPattern.begin(), tokenizedPattern.end(), 
                std::back_inserter(intTokenizedPattern), 
                [](const std::string & str){ return (std::absstoi(str) > 0 ? std::stoi(str) - 1 : throw "Input less than one");});
            validPattern = true;
        } catch(...){
            tokenizedPattern.clear();
            intTokenizedPattern.clear();
            validPattern = false;
        }
    } while(!validPattern);

    return intTokenizedPattern;
}

In the output above, it is deciphered to say "sail at seven" (null ciphers are not used in the modern age of cryptography).

One problem I came across was with integers in the pattern less than 1. For example, if the number 0 was entered, it would be come -1 in the lambda, and that would create many problems. I patched it haphazardly with an std::abs(), any help there would be useful.

#include <iostream>
#include <vector>
#include <sstream>
#include <iterator>
#include <algorithm>

std::string getString();
std::vector<std::string> tokenize(const std::string & str);
std::vector<int> getPattern();

int main(){
    std::string input;
    std::vector<std::string> words;
    std::vector<int> pattern;
    do{
        if(words.size() != pattern.size()){
            std::cout << "\nError: Number of words must be equal to number of integers in pattern.";
        }
        input = getString();
        words = tokenize(input);
        pattern = getPattern();
    } while(words.size() != pattern.size());

    for(int i = 0; i < words.size(); ++i){
        if(words[i].length() > pattern[i]){
            std::string str = words[i];
            std::cout << str[pattern[i]];
        }
    }

    std::cout << '\n';
    return 0;
}

std::string getString(){
    std::cout << "Seperate words with spaces.\nInput string: ";
    std::string input;
    std::getline(std::cin, input);
    return input;
}

std::vector<std::string> tokenize(const std::string & str){
    std::stringstream ss(str);
    std::istream_iterator<std::string> begin(ss);
    std::istream_iterator<std::string> end;
    std::vector<std::string> words(begin, end);
    return words;
}

std::vector<int> getPattern(){
    std::string pattern;
    std::vector<int> intTokenizedPattern;
    bool validPattern;
    do{
        std::cout << "Seperate positive integers with spaces: ";
        std::getline(std::cin, pattern);
        std::vector<std::string> tokenizedPattern = tokenize(pattern);
        try{
            std::transform(tokenizedPattern.begin(), tokenizedPattern.end(), 
                std::back_inserter(intTokenizedPattern), 
                [](const std::string & str){ return std::abs(std::stoi(str) - 1);});
            validPattern = true;
        } catch(...){
            validPattern = false;
        }
    } while(!validPattern);

    return intTokenizedPattern;
}

In the output above, it is deciphered to say "sail at seven" (null ciphers are not used in the modern age of cryptography).

One problem I came across was with integers in the pattern less than 1. For example, if the number 0 was entered, it would be come -1 in the lambda, and that would create many problems. I patched it haphazardly with an std::abs(), any help there would be useful.

#include <iostream>
#include <vector>
#include <sstream>
#include <iterator>
#include <algorithm>

std::string getString();
std::vector<std::string> tokenize(const std::string & str);
std::vector<int> getPattern();

int main(){
    std::string input;
    std::vector<std::string> words;
    std::vector<int> pattern;
    do{
        if(words.size() != pattern.size()){
            std::cout << "\nError: Number of words must be equal to number of integers in pattern.";
        }
        input = getString();
        words = tokenize(input);
        pattern = getPattern();
    } while(words.size() != pattern.size());

    for(int i = 0; i < words.size(); ++i){
        if(words[i].length() > pattern[i]){
            std::string str = words[i];
            std::cout << str[pattern[i]];
        }
    }

    std::cout << '\n';
    return 0;
}

std::string getString(){
    std::cout << "Seperate words with spaces.\nInput string: ";
    std::string input;
    std::getline(std::cin, input);
    return input;
}

std::vector<std::string> tokenize(const std::string & str){
    std::stringstream ss(str);
    std::istream_iterator<std::string> begin(ss);
    std::istream_iterator<std::string> end;
    std::vector<std::string> words(begin, end);
    return words;
}

std::vector<int> getPattern(){
    std::string pattern;
    std::vector<int> intTokenizedPattern;
    bool validPattern;
    do{
        std::cout << "Seperate positive integers with spaces: ";
        std::getline(std::cin, pattern);
        std::vector<std::string> tokenizedPattern = tokenize(pattern);
        try{
            std::transform(tokenizedPattern.begin(), tokenizedPattern.end(), 
                std::back_inserter(intTokenizedPattern), 
                [](const std::string & str){ return (std::stoi(str) > 0 ? std::stoi(str) - 1 : throw "Input less than one");});
            validPattern = true;
        } catch(...){
            tokenizedPattern.clear();
            intTokenizedPattern.clear();
            validPattern = false;
        }
    } while(!validPattern);

    return intTokenizedPattern;
}

In the output above, it is deciphered to say "sail at seven" (null ciphers are not used in the modern age of cryptography).

Source Link
esote
  • 3.8k
  • 2
  • 23
  • 44

Vector-based Null Cipher

Continuing with my series of cipher programs, I hastily wrote a null cipher program, and I was wondering how it could be improved:

#include <iostream>
#include <vector>
#include <sstream>
#include <iterator>
#include <algorithm>

std::string getString();
std::vector<std::string> tokenize(const std::string & str);
std::vector<int> getPattern();

int main(){
    std::string input;
    std::vector<std::string> words;
    std::vector<int> pattern;
    do{
        if(words.size() != pattern.size()){
            std::cout << "\nError: Number of words must be equal to number of integers in pattern.";
        }
        input = getString();
        words = tokenize(input);
        pattern = getPattern();
    } while(words.size() != pattern.size());

    for(int i = 0; i < words.size(); ++i){
        if(words[i].length() > pattern[i]){
            std::string str = words[i];
            std::cout << str[pattern[i]];
        }
    }

    std::cout << '\n';
    return 0;
}

std::string getString(){
    std::cout << "Seperate words with spaces.\nInput string: ";
    std::string input;
    std::getline(std::cin, input);
    return input;
}

std::vector<std::string> tokenize(const std::string & str){
    std::stringstream ss(str);
    std::istream_iterator<std::string> begin(ss);
    std::istream_iterator<std::string> end;
    std::vector<std::string> words(begin, end);
    return words;
}

std::vector<int> getPattern(){
    std::string pattern;
    std::vector<int> intTokenizedPattern;
    bool validPattern;
    do{
        std::cout << "Seperate positive integers with spaces: ";
        std::getline(std::cin, pattern);
        std::vector<std::string> tokenizedPattern = tokenize(pattern);
        try{
            std::transform(tokenizedPattern.begin(), tokenizedPattern.end(), 
                std::back_inserter(intTokenizedPattern), 
                [](const std::string & str){ return std::abs(std::stoi(str) - 1);});
            validPattern = true;
        } catch(...){
            validPattern = false;
        }
    } while(!validPattern);

    return intTokenizedPattern;
}

Here is an example input/output:

Seperate words with spaces.
Input string: Susan says Gail lies. Matt lets Susan feel jovial. Elated angry?
Seperate positive integers with spaces: 1 2 3 1 2 3 1 2 3 1 2
SailatSevEn

In the output above, it is deciphered to say "sail at seven" (null ciphers are not used in the modern age of cryptography).

One problem I came across was with integers in the pattern less than 1. For example, if the number 0 was entered, it would be come -1 in the lambda, and that would create many problems. I patched it haphazardly with an std::abs(), any help there would be useful.

In my program, I verify that the number of elements in the words and pattern vectors is equal. I also verify that the elements in the pattern vector are all actual integers (which is done in the try-catch loop).

I found it interesting that at this time this is the only null cipher program on Code Review, so it could also prove helpful to future viewers.

How can this code be improved?