From part of a cryptanalysis tool I was writing, the other day.
A way of obtaining possible XOR'ed string values.

If you ever get to the point in the analysis that you can simply XOR the string to get closer towards your goal, of finding a weakness, this might be what you need for the job.

Assuming that the value that was XOR'ed was an ASCII value 32-254(typical range),
all we have to do is loop about XOR'ing, and checking if it's in that range.
Of course.... there's still probably more work to do; even, after you create a list of possible XOR values, but it's a step closer.

Note: Small input such as, "stuff", will create over a hundred possible values, but input such as, "Stuff.", will generate a nice concise list.

Hope this helps you in analyzing, and strengthening your next encryption algorithm.

#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;

void          SmartXOR(string str);

int main()
{
    srand(time(NULL));
    
    string input;
    int    stuff = rand() % 256,
           randm = rand() % 256;
    
    cout << "Type something: ";
    getline(cin, input);
    
    /*create a very random value to be XOR'ed on
      Negatives work too, I believe.*/
    for(int i = 0; i < input.length(); i++)
    {
            input[i] ^= randm;
            for(int j = 0; j < stuff; j++)
            {
               input[i] ^= j;
            }
    }
    
    cout << "XOR'ed it to: "<< input << endl
         << "Now attempting to crack the XOR value."
         << endl << endl;
    
    SmartXOR(input);
    
    cout << endl
         << "Now strike Return with all the strength you can!";
    
    getchar();
    return(0);
}

void          SmartXOR(string str)
{
    ofstream out;
    bool     saveline = true;
    
    out.open("XOR.txt");
    
    if(out.is_open())
    {
        for(int j = 0; j < 256; j++)
        {
            for(int k = 0; k < str.length(); k++)
            {
                str[k] ^= j;
                
                if(!(str[k] > 31) || !(str[k] < 255))
                { 
                    /*invalid range of typical data*/
                    saveline = false; 
                }
            }

            if(saveline) 
            { 
              /*save it in a pretty format*/
              out << "xor[" << j << "] " 
                  << str << endl;
            }
        
            /*undo, and reset things*/
            for(int k = 0; k < str.length(); k++)
            {
                str[k] ^= j;
            }
            
            saveline = true;
        }
        
        cout << "Saved to XOR.txt" << endl;
    }
    else
    {
        cout << "\"Error generating XOR.txt!\"" << endl;
    }
}

Oh yeah, it's pretty easy to incorporate different incremental XOR'ing(or detect it), but not spastic patternized values(that's hard to undo).

Good try!
When you XOR your input with a random number, what is the purpose of XOR'ing it with another random number a that same number of times?(See the lines after "Type something:"
Do you think it will get more random? It won't get less decipherable. In fact you're XOR'ing one char with another which is "easy" to decipher. But carry on! You are on an honorable path!

The extra loop is actually just a place holder for something else I plan on doing, latter.
This technically a prototype and only works in linear fashion, I have alot of code to go still, but it demonstrates the point of the function. I also have a lot of other functions half finished in my program right now.
Next weekend I plan on adding more passes, and pattern detections of sentences for less guessing, till then I have school to worry about.

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.