Book Cipher C++

Hi, I have read two previous posts on this forum about coding a Book Cipher in C++. I am very very new to C++ and have a lot of trouble trying to figure out a few things. I am trying to encode a text file using two input files and output to a new file. I need to get and store all the characters of one file and then find those characters in the second file and out put the line number(index) and the character position(index) in that line. Any feedback or hints would be greatly appreciated.

Thank you.
Hello. I understand what you are trying to do, but I don't understand how you want to cipherize your text. The way you explained the method is not clear for me. Sorry :/
However to open and read a text file you could do something more or less similar with this code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <fstream>
#include <string>

int main() 
{
    std::ifstream myFile;
    myFile.open("test.txt");
    std::string myText;

    if (myFile.is_open()) 
    {	// file is open - ready to read
	while (myFile) 
	{   // read and display text
	    std::getline(myFile, myText);
	    std::cout << myText << std::endl;
	}
    }
    else // something goes wrong here!
	std::cout << "cannot read the file" << std::endl;

    return 0;
}
Last edited on
Another example?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <fstream>
#include <string>

int main() 
{
    std::ifstream myFile;
    std::ofstream secretFile("secretFile.txt");
    myFile.open("test.txt"); // original file

    std::string myText;

    if (myFile.is_open()) 
    {	// file is open - ready to read
	while (myFile) 
	{   // read and display text
	    std::getline(myFile, myText);
	    std::cout << myText << std::endl;
	    // you can cipherize your text here and write it in another text file
	    // as a simple example, strings are inverted :)
	    reverse(myText.begin(), myText.end());
	    secretFile << myText << std::endl; // copy new text
	}
    }
    else // something goes wrong here!
        std::cout << "cannot read the file" << std::endl;

    secretFile.close();
    return 0;
}


The original text and its pseudo cipherization copied in another file :

Fly me to the moon
Let me play among the stars
Let me see what spring is like on
A-Jupiter and Mars
In other words, hold my hand
In other words, baby, kiss me



noom eht ot em ylF
srats eht gnoma yalp em teL
no ekil si gnirps tahw ees em teL
sraM dna retipuJ-A
dnah ym dloh ,sdrow rehto nI
em ssik ,ybab ,sdrow rehto nI
Last edited on
Hi thank you for your response, I really appreciate your help. Ill give an example, may this will clear it up for you.

File1 contains the string "my bad".
i need to read this file, store the characters somewhere, maybe a map? These are the characters I need to find in another text file.

File2 contains the contents:
mary had
a little
lamb

I need to find the characters from the first file in this file and report the line number it was found in as well as the character position in that line.

So, for the character "m" it can either be (0, 0) -> Line 0 Index 0 OR (2, 2) Line 2, Index 2

These numbers, I then need to write in a new file.

I hope this clears this up for you. It is confusing I know.
You have some letters and you want to find their occurences in another text?
As example, my secret word is "love" :)

Using my previous song, I have for the first letter L:
0, 2 ; 1, 0 ; 1, 8 ; 2, 0 ; 3, 26; ....
Last edited on
Yes I think that is what I am getting at
Last edited on
Sorry. I did not respond immediately. I am in France - and for me it was a time for sleeping. So I guess that we have everything in order to create your cipherization program.
I showed to you how to open, read and write files...
So we can open the second one with its password, storing it.
We open the first one with the text which must be read. For each letter from the password, we search all occurences, storing them in a vector<pair<int, int>> for the string index and the letter index. I will try to create a prototype this morning. Stay tuned :)

PS : respectfully don't post the same request even if you improve the question please.
Last edited on
I coded this one. I don't know if it fits with your will :/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <fstream>
#include <unordered_set>
#include <string>

int main()
{   // open text file with password
    std::ifstream myPassword;
    myPassword.open("password.txt");
    std::string pw;

    std::getline(myPassword, pw); // we got it as a string
    std::unordered_set<char> log; // erase multiple letters
    pw.erase(std::remove_if(pw.begin(), pw.end(), [&](char const c) { return !(log.insert(c).second); }), pw.end());
    // open original text file
    std::ifstream myFile;
    myFile.open("test.txt");
    std::string myText;
    // string index
    int s = 0; 

    if (myFile.is_open())
    {	// file is open - ready to read
        while (myFile)
        {   // read and display string
            std::getline(myFile, myText);
            std::cout << myText << std::endl;

            for (int i = 0; i < myText.length(); i++)
                for (int j = 0; j < pw.length(); j++)
                    if (myText[i] == pw[j] && pw[j] != ' ')
                        std::cout << "String " << s << " Letter " << pw[j] << " at[" << s << ", " << i << "]" << std::endl;
            s++; // increment text string - next
        }
    }
    else // something goes wrong here!
        std::cout << "cannot read the file" << std::endl;

    return 0;
}


So for the password looove (which becomes simply love after clean-up process) and using the previous text - Fly me to the moon, I have this output :


Fly me to the moon
String 0 Letter l at[0, 1]
String 0 Letter e at[0, 5]
String 0 Letter o at[0, 8]
String 0 Letter e at[0, 12]
String 0 Letter o at[0, 15]
String 0 Letter o at[0, 16]
Let me play up there with those stars
String 1 Letter e at[1, 1]
String 1 Letter e at[1, 5]
String 1 Letter l at[1, 8]
String 1 Letter e at[1, 17]
String 1 Letter e at[1, 19]
String 1 Letter o at[1, 28]
String 1 Letter e at[1, 30]
Let me see what spring is like on Jupiter and Mars
String 2 Letter e at[2, 1]
String 2 Letter e at[2, 5]
String 2 Letter e at[2, 8]
String 2 Letter e at[2, 9]
String 2 Letter l at[2, 26]
String 2 Letter e at[2, 29]
String 2 Letter o at[2, 31]
String 2 Letter e at[2, 39]
In other words hold my hand
String 3 Letter o at[3, 3]
String 3 Letter e at[3, 6]
String 3 Letter o at[3, 10]
String 3 Letter o at[3, 16]
String 3 Letter l at[3, 17]
In other words baby kiss me
String 4 Letter o at[4, 3]
String 4 Letter e at[4, 6]
String 4 Letter o at[4, 10]
String 4 Letter e at[4, 26]
In other words baby kiss me
String 5 Letter o at[5, 3]
String 5 Letter e at[5, 6]
String 5 Letter o at[5, 10]
String 5 Letter e at[5, 26]


As you can see, I erase all letters which appear in the password more than one time to avoid redondance. The main process does not check space, but you can add more specific chars which are not relevant. It's a first approach ++
Last edited on
Ive also seen these doing the word at a page. without the physical book, same edition, it was very difficult to crack before computers, though you needed a book with a lot of useful nouns in it.
Hi Geckoo, I am sorry for reposting I was just really looking for an answer.
Thank you for your response, is there a way to store the lineIndex and charIndex value in a map and then iterate through the map to print those values? If not, thank you again for your help!
Hello. Yes you can easily store all output as vectors. We have two integers for each letter occurrence. I guess that the best way could be to use vector<pair<int, int>>, but if you want to get another parameters like the letter, we can use a structure vector instead a pair vector. Finally we have at end this code :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <fstream>
#include <unordered_set>
#include <string>
#include <vector>
// a pair vector in order to store all data
std::vector<std::pair<int, int>> occ;

int main()
{   // open text file with password
    std::ifstream myPassword;
    myPassword.open("password.txt");
    std::string pw;

    std::getline(myPassword, pw); // we got it as a string
    std::unordered_set<char> log; // erase multiple letters
    pw.erase(std::remove_if(pw.begin(), pw.end(), [&](char const c) { return !(log.insert(c).second); }), pw.end());
    // open original text file
    std::ifstream myFile;
    myFile.open("test.txt");
    std::string myText;
    // string index
    int s = 0;

    if (myFile.is_open())
    {	// file is open - ready to read
        while (myFile)
        {   // read and display string
            std::getline(myFile, myText);
            std::cout << myText << std::endl;

            for (int i = 0; i < myText.length(); i++)
                for (int j = 0; j < pw.length(); j++)
                    if (myText[i] == pw[j] && pw[j] != ' ')
                        occ.push_back(std::make_pair(s, i)); // adding a new pair to the vector 
                    
            s++; // increment text string - next
        }
        // display all pair
        for (int k = 0; k < occ.size(); k++)
            std::cout << "[" << occ[k].first << "," << occ[k].second << "]" << std::endl;
    }
    else // something goes wrong here!
        std::cout << "cannot read the file" << std::endl;

    return 0;
}



Fly me to the moon
Let me play among the stars
Let me see what spring is like on
A-Jupiter and Mars
In other words, hold my hand
In other words, baby, kiss me

[0,1]
[0,5]
[0,8]
[0,12]
[0,15]
[0,16]
[1,1]
[1,5]
[1,8]
[1,14]
[1,20]
[2,1]
[2,5]
[2,8]
[2,9]
[2,26]
[2,29]
[2,31]
[3,7]
[4,3]
[4,6]
[4,10]
[4,17]
[4,18]
[5,3]
[5,6]
[5,10]
[5,28]


Which output you want?



Last edited on
With a structure instead of a limited vector<pair<int, int>>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <fstream>
#include <unordered_set>
#include <string>
#include <vector>

struct data
{
    char letter;
    int string;
    int index;
};
// a structure vector in order to store all data
std::vector<data> occ;
// a function to create and add a new data structure
void newData(char c, int s, int i)
{
    data d;
    d.letter = c;
    d.string = s;
    d.index = i;
    // store the new data structure
    occ.push_back(d);
}

int main()
{   // open text file with password
    std::ifstream myPassword;
    myPassword.open("password.txt");
    std::string pw;

    std::getline(myPassword, pw); // we got it as a string
    std::unordered_set<char> log; // erase multiple letters
    pw.erase(std::remove_if(pw.begin(), pw.end(), [&](char const c) { return !(log.insert(c).second); }), pw.end());
    // open original text file
    std::ifstream myFile;
    myFile.open("test.txt");
    std::string myText;
    // string index
    int s = 0;

    if (myFile.is_open())
    {	// file is open - ready to read
        while (myFile)
        {   // read and display string
            std::getline(myFile, myText);
            std::cout << myText << std::endl;

            for (int i = 0; i < myText.length(); i++)
                for (int j = 0; j < pw.length(); j++)
                    if (myText[i] == pw[j] && pw[j] != ' ')
                        newData(pw[j], s, i); // adding a new structure to the vector 
                    
            s++; // increment text string - next
        }
        // show every structure which have been stored in our vector
        for (int k = 0; k < occ.size(); k++)
            std::cout << "Letter " << occ[k].letter << " [" << occ[k].string << "," << occ[k].index << "]" << std::endl;
    }
    else // something goes wrong here!
        std::cout << "cannot read the file" << std::endl;

    return 0;
}



Fly me to the moon
Let me play among the stars
Let me see what spring is like on
A-Jupiter and Mars
In other words, hold my hand
In other words, baby, kiss me

Letter l [0,1]
Letter e [0,5]
Letter o [0,8]
Letter e [0,12]
Letter o [0,15]
Letter o [0,16]
Letter e [1,1]
Letter e [1,5]
Letter l [1,8]
Letter o [1,14]
Letter e [1,20]
Letter e [2,1]
Letter e [2,5]
Letter e [2,8]
Letter e [2,9]
Letter l [2,26]
Letter e [2,29]
Letter o [2,31]
Letter e [3,7]
Letter o [4,3]
Letter e [4,6]
Letter o [4,10]
Letter o [4,17]
Letter l [4,18]
Letter o [5,3]
Letter e [5,6]
Letter o [5,10]
Letter e [5,28]


I think we've about covered it :)
Last edited on
I think that finally I understand what you are trying to do. Now using this structure vector, you want to open a third file in order to check all letters occupying these s/i position. This way you can obtain plain text among many letters. Right? Interesting method ++
Yes, thank you have been so much help! You are the best!!!
Topic archived. No new replies allowed.