Trying to make a VERY basic cipher program

im trying to make a cypher program, and it was working, now its just showing numbers. dont get me wrong, i know y it is showing numbers (dont know how i got those specific numbers or what they really mean, but i know what i did to make em appear), but now that it is i like it better with it outputting numbers. however, the numbered sequences are always 7 digits, for example, a=8003594, b=7938058, so ab=80035947938058.

i would like a way to have another program decypher every 7 numbers into a letter, but i cant figure it out, any help would be nice.

also, maybe a way to export my code to a text, or a way to have the program read a .txt of numbers and decypher it? so it reads the first 7 numbers, then compares it to some list or something? then outputs the letter

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <cstdlib>
#include <iostream>
using namespace std;

char a, b, c;
int up;

int main(int argc, char *argv[])
{
    loop:
    cin >> a;
    if (a == 'a')
    cout << 'z \n';
    else
    if (a == 'b')
    cout << 'y \n';
    else
    if (a == 'c')
    cout << 'x \n';
    else
    if (a == 'd')
    cout << 'w \n';
    else
    if (a == 'e')
    cout << 'v \n';
    else
    if (a == 'f')
    cout << 'u \n';
    else
    if (a == 'g')
    cout << 't \n';
    else
    if (a == 'h')
    cout << 's \n';
    else
    if (a == 'i')
    cout << 'r \n';
    else
    if (a == 'j')
    cout << 'q \n';
    else
    if (a == 'k')
    cout << 'p \n';
    else
    if (a == 'l')
    cout << 'o \n';
    else
    if (a == 'm')
    cout << 'n \n';
    else
    if (a == 'n')
    cout << 'm \n';
    else
    if (a == 'o')
    cout << 'l \n';
    else
    if (a == 'p')
    cout << 'k \n';
    else
    if (a == 'q')
    cout << 'j \n';
    else
    if (a == 'r')
    cout << 'i \n';
    else
    if (a == 's')
    cout << 'h \n';
    else
    if (a == 't')
    cout << 'g \n';
    else
    if (a == 'u')
    cout << 'f \n';
    else
    if (a == 'v')
    cout << 'e \n';
    else
    if (a == 'w')
    cout << 'd \n';
    else
    if (a == 'x')
    cout << 'c \n';
    else
    if (a == 'y')
    cout << 'b \n';
    else
    if (a == 'z')
    cout << 'a \n';
    else {
    cout << "\n Exit? \n";
    cin >> up; 
}
    if (up == 'y')
    return EXIT_SUCCESS;
    else
    goto loop;
}


and apparently, if i use caps or anything, it goes into a perpetual exit cycle, anyway to include caps?
Last edited on
Just sticking to single letters for the moment, C and C++ are case sensitive, i.e. 'z' is not the same as 'Z' so you need to use toupper() or tolower() to convert before you do any comparisons

I would also loose the goto's (their use is generally frowned upon) and use a while loop, and use an array instead of endless if else if ... statements. For 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
31
32
33
34
35
36
37
38
39
40
41
42
#include <cstdlib>
#include <iostream>
using namespace std;

char a, b, c;
const int ARRAY_LEN = 26;
char array[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};

int main(int argc, char *argv[])
{
   char up = 'n';
   int i;
   char temp;
   bool finished = false;
   
   while (toupper(up) != 'Y')
   {
      cout << "Enter Character to encode" << endl;
      cin >> temp;
      a = tolower(temp);
      finished = false;

      for (i = 0; i < ARRAY_LEN && !finished; i++)  // loop through the whole array
      {
	 if (a == array[i])  // if 'a' matches element in the array....
	 {
	    cout << array[ARRAY_LEN - 1 - i] << endl;  // count 'i' from back of array
	    finished = true; // exit loop as search is done
	 }
      }

      if (i == ARRAY_LEN) // search failed so it must have been a different key press
      {
	 cout << "\n Exit? \n";
	 cin >> up;
      }

   }

    return EXIT_SUCCESS;

}


Your numbers are because you need " instead of ' for enclosing text. The single quote ' is used to enclose a single character
1
2
3
cout << 'p' << endl;  // single character
cout << "p" << endl; // string of a single character
cout << "text" << endl; // string of multiple characters 


I'm not sure how cout was interpreting the 'z \n' etc to produce those numbers.
You could however use the ASCII number instead so instead of

 
cout << array[ARRAY_LEN - 1 - i] << endl; 


do

 
cout << (int)array[ARRAY_LEN - 1 - i] << endl; 


Taking it a step further, define another array that holds the encryption rather than just looking up the same array in reverse, and cross reference between the two.

Hope this helps
Last edited on
i give up..cant they just make the damn language easy? it so damn hard to even try to write a simple thing to a file, they need to fix the damn language, its pointless to even try to begin learning it, it makes no sense
I know its frustrating. Just take a deep breath.





There, better, isn't it?
Programming is more complicated than learning how to ride a bicycle. But if you stick with it you'll do just fine.

Here's an example of a lookup table in the way that bnbertha suggested:
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
#include <cctype>    // for the isalpha(), isupper() and toupper() functions
#include <iostream>
#include <string>
using namespace std;

char LUT[] = "slcitapeyjkuqxzohfrdvgnbmw";

int main()
  {
  string message;
  char   c;

  cout << "Please enter a message to encrypt> ";
  getline( cin, message );

  // Encrypt it using the lookup table.
  // A..Z and a..z are encrypted using the lookup table.
  // All other characters (like spaces and punctuation) are left alone.

  // For each character in the message
  for (unsigned n = 0; n < message.length(); n++)
    {
    // Only modify the character if it is in A..Z or a..z
    c = message[ n ];
    if (isalpha( c ))
      {
      if (isupper( c ))
        // If the character is uppercase then
        // get the uppercase version of the code character
        message[ n ] = toupper( LUT[ c -'A' ] );
      else
        // If the character is lowercase then
        // get the lowercase version
        message[ n ] = LUT[ c -'a' ];
      }
    }

  // Show the user the encoded message
  cout << "The encoded message is: " << message << endl;

  return 0;
  }

As an exercise, you can write a program that decodes the message. The LUT to decode the message is:

"fxcthrvqdjkbywpgmsaeluznio"

Hope this helps, and Have Fun!
i dont get what these 2 lines mean and what exactly they do, like the n++, i know it adds one to n, but what exactly is n and y would u add numbers to it?
for (unsigned n = 0; n < message.length(); n++)

message[ n ] = LUT[ c -'a' ];

like how is it pulling a character from the LUT


i figured id be better to make each letter like, a 7 number sequence like it was before, but how would i set the lut to pull the 1st 7 or the 2nd for a or b?
Last edited on
1
2
3
4
for (unsigned n = 0; n < message.length(); n++)
{
//Some Code here
}

The for loop allows you to repeat a secion of code multiple times.
In C and C++ it's a lot more flexible than most other languages, and in this example includes;
The declaration and initialisation of a local unsigned integer n (unsigned n = 0;,
A check to loop again if the value of n is less than the length of the message n < message.length();
And finally a increment on n every time round the loop n++)
Inside the body of the for loop (//Some Code here ) n is used to control the behaviour.

message[ n ] = LUT[ c -'a' ];
message is a string, which can by treated as if it were an array of characters to access individual characters in the string, so message[ n ] is the nth character in the string.

EG message = "Hello", message[1] = 'e' (starts at index 0 for first character).

LUT is also an array, so can be treated in the same way.

LUT[ c -'a' ]; is a bit of C or C++ 'trickery'.
c is a char, which is a 1 byte integer that can be treated as if it represents a character OR as a number.
c-'a' makes the computer do both! Say c = 'e', then because characters are encoded using the ASCII chart, the computer translates 'e' into 101, and 'a' into 97, subtracts 97 from 101 to get 4.
So if c = 'e', LUT[ c - 'a'] => LUT['e' - 'a'] => LUT[101-97] => LUT[4] ='t'

(Pause for breath...)

It does all start to make sense after a while, honest:-)
If you haven't done so already it's well worth taking the time to go through the tutorial on this site (http://www.cplusplus.com/doc/tutorial/) it covers most of what you need to create a wide range of programs in a fairly easy to understand manner.
Hope the above helps.


Last edited on
Sorry I muddied the water for you. Like Faldrax said, have a look at the tutorial. Each time you get stuck, post a question. Someone will help.
i tried to alter it, figured using numbers wouldnt change anything because its still pulling the 4th spot from the array for 'e' for example (at least if i understood fladrax's explination correctly), but its not working, idk why...

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
#include <cctype>    // for the isalpha(), isupper() and toupper() functions
#include <iostream>
#include <string>
using namespace std;


long test[] = { 8003594, 7938058, 7872522, 7806986, 7741450, 7675914, 7610378, 7544842, 7479306, 7413770, 7348234, 7282698, 7217162, 7151626, 7086090, 7020554, 6955018, 6889482, 6823946, 6758410, 6692874, 6627338, 6561802, 6496266, 6430730, 6365194 };

int main ()  {
  string message;
  char   c;

  cout << "Encrypt Message>";
  getline( cin, message );

  // Encrypt it using the lookup table.
  // A..Z and a..z are encrypted using the lookup table.
  // All other characters (like spaces and punctuation) are left alone.

  // For each character in the message
  for (unsigned n = 0; n < message.length(); n++)
    {
    // Only modify the character if it is in A..Z or a..z
    c = message[ n ];
    if (isalpha( c ))
      {
      if (isupper( c ))
        // If the character is uppercase then
        // get the uppercase version of the code character
        message[ n ] = toupper( test[ c -'A' ] );
      else
        // If the character is lowercase then
        // get the lowercase version
        message[ n ] = test[ c -'a' ];
      }
    }

  // Show the user the encoded message
  cout << "-->" << message << endl;

  return 0;
  }


and does this make the var for c uppercase to subtract from A, then pull the lowercase letter from the table/array and make it capital?
message[ n ] = toupper( test[ c -'A' ] );
Last edited on
i think i understand now, so the string u enter into the program gets treated like an array and u can isolate individual chars as you would with a normal array? thats the point of n, right?

still dont understand the to upper part tho, or end1


also, any way to pull what i want to encode/decode from a text, i was thinking

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
 
ofstream file;
    file.open ("encode.txt", fstream::in);
for (unsigned n = 0; n < message.length(); n++)
file.get ( n )
string message;

 if (isalpha( c ))
      {
      if (isupper( c ))
        // If the character is uppercase then
        // get the uppercase version of the code character
        message[ n ] = toupper( LUT[ c -'A' ] );
      else
        // If the character is lowercase then
        // get the lowercase version
        message[ n ] = LUT[ c -'a' ];
      }
file.close();
cout << message;

file.open ("decodedtext.txt");
file<< message;
file.close();
return 0;

dont think itll work tho
Last edited on
You've got the right idea.

All toupper() does is take lowercase letters and make them uppercase. If you are using numbers as your codes, then all you need is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for (unsigned n = 0; n < message.length(); n++)
  {
  c = message[ n ];
  if (isalpha( c ))
    {
    // The 'test' LUT only lists 26 numbers, so we need to convert our
    // A..Z's and a..z's to an index.
    //
    // So we make sure c is uppercase, then subtract 'A' to make
    // it 0..25 --which is a perfect index into the LUT.
    //
    // Also, since message[] is an array of char, we can't stick our translated
    // value back in to it. So we just 'cout' it right away.
    cout << test[ toupper( c ) -'A' ];
    }
  // if it is not an alpha (A..Z or a..z) we just ignore it. You can change this,
  // of course, but for this example...
  }


You are doing fine. The more you mess with it the more light bulbs turn on. :-)
Last edited on
....and endl flushes the buffer and puts in a new line. Flushing the buffer effectively forces what you have sent to cout out to the screen. You can put an endl anywhere in the cout line and you can put it in multiple times if you want to....

 
cout << endl << "test" << endl << "message" << endl;


There are quite a lot of manipulators you can put in that alter the way the message appears like converting numbers to hex, characters to numbers etc. look at the manipulators section here for more details
http://www.cplusplus.com/reference/iostream/

Topic archived. No new replies allowed.