Simple(?) substitution cipher help

This is a discussion on Simple(?) substitution cipher help within the C++ Programming forums, part of the General Programming Boards category; I am trying to make a simple substitution cipher. Here is what I want the program to do, and how ...

  1. #1
    Registered User
    Join Date
    Aug 2009
    Posts
    19

    Simple(?) substitution cipher help

    I am trying to make a simple substitution cipher. Here is what I want the program to do, and how I would do this by hand (the code is where I'm not getting it).
    1. Get input from the user. (1 word.)
    2. Determine string length;
    3. Get the first letter of the string, modify it based on a numeric value, replace it (IE, A+2 = C, B+2 = D, so on).
    4. Repeat until end of string.
    5. Print output.

    I am teaching myself how to program, sort of. So my knowledge of C++ is elementary.

    So far, I have the input, string length, loops, and output handled, those are easy. I need help in manipulating the string and letters.

    Can someone give a simple example of how to get the first letter of the string, then how to move to the next? And, also, how to change that letter based on a rule, ie, move two positions, etc, then replace it?

    All I have for code so far is this:
    Code:
    #include <iostream>
    #include <string>
    
    using namespace::std;
    
    int main()
    {
        string plaintext;
        cout<<"Enter your word here: \n";
        cin>> plaintext;
        int slength = plaintext.size(); //getting the size of the string;
        cout<<"That word is " << plaintext.size() <<" characters. \n";
       int loops = slength;
        while (loops < slength) 
                 /*this will be the "repeat until done" loop, running until all letters are replaced.*/
        {
        loops --;
        }
        system("PAUSE");
        return 0;
    }
    The "system("PAUSE") is only there to hold the window open.
    I also realize that I could eliminate a few variables, I will be doing that later.

    Any help would be most appreciated!

  2. #2
    Registered User
    Join Date
    Aug 2009
    Posts
    19
    One other thing... if there is another data type to use that ignores whitespace, except for a carriage return, that would be even better. Or treats whitespace as another character, and substitutes it... that's even better.

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    2,023
    There is a function, transform that can be used to apply a function to each member of an collection, such as a string.

    In this case the call would look like this:
    Code:
    #include <algorithm>
    ...
     tranform(text.begin(), text.end(), text.begin(),&transformFunc);
    Where text is the text to be in place transformed (transforming to another string is possible too, but this is simpler.), and transformFunc is the function that preforms encryption on a single character.
    Last edited by King Mir; 08-31-2009 at 12:20 AM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,023
    Quote Originally Posted by kalor_alros View Post
    One other thing... if there is another data type to use that ignores whitespace, except for a carriage return, that would be even better. Or treats whitespace as another character, and substitutes it... that's even better.
    You can use cin.getline()
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  5. #5
    Registered User
    Join Date
    Aug 2009
    Posts
    19
    Quote Originally Posted by King Mir View Post
    There is a function, transform that can be used to apply a function to each member of an collection, such as a string.

    In this case the call would look like this:
    Code:
    #include <algorithm>
    ...
     tranform(text.begin(), text.end(), text.begin(),&transformFunc);
    Where text is the text to be in place transformed (transforming to another string is possible too, but this is simpler.), and transformFunc is the function that preforms encryption on a single character.
    Ok... so sorry to be slow, but I'm not getting how to implement this. I'll try to clarify my understanding.

    I would use text.begin(), substituting my string name, in this case, plaintext.begin() and plaintext.end() to determine start and end of the string?

    Could you show a link to or a bit of code as an example of an implementation? Preferably a simple one? Not looking for an answer, as I won't learn anything, but I'm not completely understanding the definitions in the reference link.

  6. #6
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,181
    To access individual characters in a string, you can use the [] operator.

    plaintext[0] is the first character, plaintext[1] is the second, etc.

    I recommend leaving the STL for later, and learn the basics first.

  7. #7
    Registered User
    Join Date
    Aug 2009
    Posts
    19
    Ok, so i found a way to do a simple conversion to ASCII numbers. I can also get those numbers back to a letter. What I can't seem to do is get them to append to the string.

    Code:
    I have tried to use ciphertext.append(letter);
    and a few variants.

    I get the error message "invalid conversion from 'char' to 'const char'.

    I obviously can't declare this as a const type, since it needs to change. I also tried
    Code:
    ciphertext.append(char(cipher_number));
    ,

    and got the same. So, how would i go about getting that letter into a string?

    Nevermind... I found a way, albeit sloppy... created a string, and appended THAT string to my current one. It works, but is probably using lots of memory that I don't need. Suggestions on cleaning this up?

    Code:
    while (loops < slength)
        {
              cout<<int(plaintext[loops]) <<"\n"; //outputs the ascii of the letter
              cipher_num = int(plaintext[loops]); //sets the number to that value
              letter = char(cipher_num); //sets the char to the letter represented by the ascii
              cipherletter = letter; //sets the string to the char value
              ciphertext.append (cipherletter); //appends the string to the cipher text.
              loops++;
        }
    Last edited by kalor_alros; 08-31-2009 at 01:52 AM.

  8. #8
    Registered User
    Join Date
    Apr 2006
    Posts
    2,023
    Quote Originally Posted by kalor_alros View Post
    Ok... so sorry to be slow, but I'm not getting how to implement this. I'll try to clarify my understanding.

    I would use text.begin(), substituting my string name, in this case, plaintext.begin() and plaintext.end() to determine start and end of the string?

    Could you show a link to or a bit of code as an example of an implementation? Preferably a simple one? Not looking for an answer, as I won't learn anything, but I'm not completely understanding the definitions in the reference link.
    text.begin() returns an iterator to the first character of the string. This is used to access each element of the string in order starting at the beginning. text.begin() Is an iterator representing when to stop transforming, it represents the end of the string.

    Yes, you could substitute plaintext for text, except that since I'm showing an in-place copy, plaintext would no longer be an appropriate name. You could use the code I gave as is, as long as you rename plaintext to text, and write a cipher function.

    To summarize the transform function further:
    An iterator is something that is used to access elements in a container (a collection of objects) using *iterator and, can be used to step through the container by incrementing and decrementing the iterator, or sometimes adding an integer to it.
    A String is considered a container of characters.
    The transform function uses three such iterators. Two to specify the range to get data from, and one specifying where the range of the result starts. The last parameter is a function to apply to each input element, to get the result element.

    The definition of transform looks weird, because it uses templates to make it so that you can call it with different types.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    2,023
    Quote Originally Posted by kalor_alros View Post
    Ok, so i found a way to do a simple conversion to ASCII numbers. I can also get those numbers back to a letter. What I can't seem to do is get them to append to the string. ...
    Just use cipherletter += cipher_num. append() is mainly for appending thins that can't be specified with one parameter. Also, there is no reason to make cipher_num an integer, you can just use a char, and treat it like a number.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  10. #10
    Registered User
    Join Date
    Aug 2009
    Posts
    19
    Much appreciated... I did get it to work, still sloppy, but I am re-writing a much more elegant system now... though not up to professional standards, and hopefully my coding is better when I go to school, but it works. This is mostly for fun anyways.

    I tried to use a couple different methods for the cipher_num, and most of them returned datatype errors, such as directly appending the char(ascii value) directly to the string... it gave a "redeclaration from data type const char to char" error. It would however, allow me to make a string = that same char, from the same variable, then append the string to the other.

    so i did:
    cipher_let = char(cipher_num);
    cipher_str = cipher_let;
    actual_str.append(cipher_str);

    which, while being sloppy, was entirely functional.

  11. #11
    Registered User
    Join Date
    Apr 2006
    Posts
    2,023
    Just do
    actual_str += char(cipher_num);

    You can also use push_back(), though the above is more common.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  12. #12
    Registered User
    Join Date
    Aug 2009
    Posts
    19
    ok. I have a functioning encrypt/decrypt program working. For the simplicity of what it does, the encryption is strong enough (pseudo-random letter shifts, determined by odd/even, multiple of 3, and multiple of 4, recorded for the user in a text file.)

    What I want to improve is the encryption key.

    It's a practice in theory for me. I want to find a static method to generate a key, that's complicated enough that breaking it by hand is highly improbable (without knowing the system) but simple enough that it can be generated quickly, without anything too complex on the code side.

    What I am really leaning towards is a computerized playfair system. Here's what the function would need to do.

    *Build a "board", 5X5. (Multidimensional array? Hopefully not, I don't get along with arrays)
    *Fill the board with the alphabet using the users key, never repeating a letter.
    *Break the plain text into pairs. (should be simple enough, just pulling letters out from a string)
    * Find their locations on the "board" (coordinates, as an example? IE, 1,2 and 2, 2, for say, A and B)
    * Find the squares on the board that match up distance from each other, forming a square.
    *replace A and B with their counterparts.
    *append the encrypted text to a string, removing whitespace.

    so. Would a multidimensional array (say char table[5][5] be what I need to use to do this in the most efficient manner?

    I have a hard time verbalizing what the cipher does, here's the URL to the wikipedia entry:
    Playfair cipher - Wikipedia, the free encyclopedia

    Any advice would be extremely helpful!

  13. #13
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,189
    playfair is fairly easy to break using frequency analysis, especially with modern computers. Because the same digram will always encode to the same pair of letters, it doesn't significantly increase the brute force necessary. If you have a sample of plaintext and its equivalent ciphertext key extraction is trivial. If you have enough ciphertext frequency analysis is straight froward. Cribs can also be used, as with any substitution cipher. For example, in any lengthy english text the letters th will appear very often.

    Now if you want a real challenge, try this cipher I recently sent to a friend at NSA -

    9a af 4e 54 67 03 b7 ab 23 4a 01 eb ff 5c e0 7b 4f e6 39 2f fa 5e 97 43 ee 05 eb 3e a6 28 7e 7f c6 cf f3 e5 a1 b4 62 09 fd e2 56 1a 82 e7 59 c4 84 49 32 23 67 bf 87 7f 18 b8 32 41 c3 4b 82 c3 af c1 fc 53 ad ce 97 ad 15 15 5a 0f f7 2d b9 97 8a 6e d2 7f 01 42 f7 6f 7a a2 ab 89 9a e1 57 6d 9b f2 46 67 d5 f8 2a 2f 8d db aa 48 22 5d 22 23 5f 06 c7 97 fc b5 52 38 26 14 8c 15 7a 87 fe 5b 33 32 88 80 0f dd 9c b0 14 b3 19 3b 43 b9 53 8b 33 8b 13 83 fc 14 b3 dc 67 40 26 d5 0b cf 2a ed da c1 44 a6 88 07 f2 06 43 50 0a ce 6d b7 0b cb 78 90 4f 76 54 bd f7 9e 27 3e e5 a5 81 43 1c 8b b1 b7 34 b7 36 1e 2a c0 f4 8f cb dd b5 f8 c2 e3 0d ed 80 0e 97 d6 b0 09 d2 7a bc 44 07 d6 c8 df 56 70 b3 e8 77 52 d5 05 bd 26 50 c5 d3 79 38 7d 12 45 f9 d8 08 3e 54 78 e7 5d ce c4 3f 59 4f a9 4c bf 22 83 6d 31 19 07 0e e7 28 72 ef 29 45 20 0e f6 48 de 9c 8b 4b 25 04 27 16 3b 9b 30 a8 ff 58 0e 05 4c ab 13 a9 e8 62 e4 17 ec e8 d7 d2 f2 e8 0b fe 9c 65 28 22 77 a2 32 95 a4 ed de 34 0d c3 3d 03 71 26 37 82 30 e2 1b 08 84 3e 5b c0 91 c2 c3 65 32 f7 9e 10 7a 5a 75 21 2f 68 c3 86 d5 72 24 a5 24 44 1e 1c 7e 9a d9 ac f8 48 0b f7 6e 48 6e 0d 4e 82 c5 72 f4 37 f1 9f 47 0f db c6 2f 38 3f 94 56 25 4d e0 f1 76 9f ee 9b 92 9e dc f4 a0 86 63 06 f7 e2 f7 09 4b 2f 18 bd fe 7a 55 0e 97 3d 1f 8e df ef 2d b3 e7 6f f4 ad 64 ec e3 4f 10 8c bf f0 71 9a b1 11 a2 ff 87 f3 f5 c1 e3 ff a6 2a e1 b3 c0 ea d1 91 6a c3 35 16 28 e0 f4 cd b4 47 cb 20 0a 69 93 6d 13 b0 44 82 a5 cd 43 ee d2 1e 97 4e d1 ec 5e 34 c7 d5 80 84 43 11 c7 32 d9 c6 da e7 9c 36 e3 75 fb 22 74 af 7e 57 6f 73

    It is text, taken from a classic novel.
    It is English
    The cipher is not a one time pad
    Until you can build a working general purpose reprogrammable computer out of basic components from radio shack, you are not fit to call yourself a programmer in my presence. This is cwhizard, signing off.

  14. #14
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    478
    Quote Originally Posted by abachler View Post
    playfair is fairly easy to break using frequency analysis, especially with modern computers. Because the same digram will always encode to the same pair of letters, it doesn't significantly increase the brute force necessary. If you have a sample of plaintext and its equivalent ciphertext key extraction is trivial. If you have enough ciphertext frequency analysis is straight froward. Cribs can also be used, as with any substitution cipher. For example, in any lengthy english text the letters th will appear very often.

    Now if you want a real challenge, try this cipher I recently sent to a friend at NSA -

    9a af 4e 54 67 03 b7 ab 23 4a 01 eb ff 5c e0 7b 4f e6 39 2f fa 5e 97 43 ee 05 eb 3e a6 28 7e 7f c6 cf f3 e5 a1 b4 62 09 fd e2 56 1a 82 e7 59 c4 84 49 32 23 67 bf 87 7f 18 b8 32 41 c3 4b 82 c3 af c1 fc 53 ad ce 97 ad 15 15 5a 0f f7 2d b9 97 8a 6e d2 7f 01 42 f7 6f 7a a2 ab 89 9a e1 57 6d 9b f2 46 67 d5 f8 2a 2f 8d db aa 48 22 5d 22 23 5f 06 c7 97 fc b5 52 38 26 14 8c 15 7a 87 fe 5b 33 32 88 80 0f dd 9c b0 14 b3 19 3b 43 b9 53 8b 33 8b 13 83 fc 14 b3 dc 67 40 26 d5 0b cf 2a ed da c1 44 a6 88 07 f2 06 43 50 0a ce 6d b7 0b cb 78 90 4f 76 54 bd f7 9e 27 3e e5 a5 81 43 1c 8b b1 b7 34 b7 36 1e 2a c0 f4 8f cb dd b5 f8 c2 e3 0d ed 80 0e 97 d6 b0 09 d2 7a bc 44 07 d6 c8 df 56 70 b3 e8 77 52 d5 05 bd 26 50 c5 d3 79 38 7d 12 45 f9 d8 08 3e 54 78 e7 5d ce c4 3f 59 4f a9 4c bf 22 83 6d 31 19 07 0e e7 28 72 ef 29 45 20 0e f6 48 de 9c 8b 4b 25 04 27 16 3b 9b 30 a8 ff 58 0e 05 4c ab 13 a9 e8 62 e4 17 ec e8 d7 d2 f2 e8 0b fe 9c 65 28 22 77 a2 32 95 a4 ed de 34 0d c3 3d 03 71 26 37 82 30 e2 1b 08 84 3e 5b c0 91 c2 c3 65 32 f7 9e 10 7a 5a 75 21 2f 68 c3 86 d5 72 24 a5 24 44 1e 1c 7e 9a d9 ac f8 48 0b f7 6e 48 6e 0d 4e 82 c5 72 f4 37 f1 9f 47 0f db c6 2f 38 3f 94 56 25 4d e0 f1 76 9f ee 9b 92 9e dc f4 a0 86 63 06 f7 e2 f7 09 4b 2f 18 bd fe 7a 55 0e 97 3d 1f 8e df ef 2d b3 e7 6f f4 ad 64 ec e3 4f 10 8c bf f0 71 9a b1 11 a2 ff 87 f3 f5 c1 e3 ff a6 2a e1 b3 c0 ea d1 91 6a c3 35 16 28 e0 f4 cd b4 47 cb 20 0a 69 93 6d 13 b0 44 82 a5 cd 43 ee d2 1e 97 4e d1 ec 5e 34 c7 d5 80 84 43 11 c7 32 d9 c6 da e7 9c 36 e3 75 fb 22 74 af 7e 57 6f 73

    It is text, taken from a classic novel.
    It is English
    The cipher is not a one time pad
    I sincerely hope you aren't serious.

    You do realize that the strength of an encryption algorithm should not depend on how well you can hide the algorithm itself, right? I could easily give you a bunch of random letters and tell you to crack it, but the challenge wouldn't be to break the algorithm, but rather to discover it.

    Your friend at the NSA should tell you this.
    "What's up, Doc?"
    "'Up' is a relative concept. It has no intrinsic value."

  15. #15
    Registered User
    Join Date
    Aug 2009
    Posts
    19
    The object of this program (for me) isn't to utilize any form of strong encryption, it's to take an area of interest of mine, and apply it to another in a way that challenges my skills, and develop new ones.

    I chose playfair because it's a more advanced set of coding skills, not a more advanced code (than I used in another program). It's also a system that is simple to learn by hand, and knowing the system SHOULD make it easier to code, as I don't have to learn a new form of encryption first, then write the code for something that I might or might not be using properly.

    My first question still goes back to the table... would I use a character array, 5X5, to enter the alphabet into? Or is there a simpler way to accomplish the same thing?

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. creating very simple text editor using c
    By if13121 in forum C Programming
    Replies: 9
    Last Post: 10-19-2010, 05:26 PM
  2. About aes
    By gumit in forum C Programming
    Replies: 13
    Last Post: 10-24-2006, 03:42 PM
  3. Substitution Cipher Program Problem...
    By Junior89 in forum C++ Programming
    Replies: 13
    Last Post: 12-28-2005, 04:02 PM
  4. Simple message encryption
    By Vicious in forum C++ Programming
    Replies: 10
    Last Post: 11-07-2004, 10:48 PM
  5. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21