Thread: Caeser Cipher

  1. #1
    Registered User L_U_K_E's Avatar
    Join Date
    Apr 2006
    Posts
    106

    Caeser Cipher

    Recently i have been playing around with caeser cipher and i came up with this:

    Code:
        string a = "thisisit";
        string ciphertext;
        int b = a.length();
        int offset = 3;
        int offset2 = 5;
        int offset3 = 2;
        for (int i = 0; i < b; ++i)
        {
            ciphertext += ( ( (a[i] - 'a') + (offset - offset2) / (offset3 * offset) - offset2) %26) + 'a';
        }
        cout<< ciphertext <<endl;
        cin.get();
    And it works to encrypt the data but how do i decrypt it after that? I was thinking maybe something along the lines of reversing this part of the code:

    [code]
    ciphertext += ( ( (a[i] - 'a') + (offset - offset2) / (offset3 * offset) - offset2) %26) + 'a';
    [code]

    P.S i am quite a newb and have never done anything like this before so be gentile(lol).

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Break your expression down into its component parts. It's way too complicated, especially if you're a beginner. Once it's simplified, you can find ways to optimize it and easily reverse it.
    My best code is written with the delete key.

  3. #3
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    My other reply got deleted. I don't know what those offset things are, but I think encryption is just

    Code:
    ciphertext += (((a[i] - 'a') + shift_value) % 26) + 'a';
    You get the offset in the alphabet, shift it, modulus to make it wrap, and then make it ASCII again.

    And then decryption, you can subtract the shift value from (a[i] - 'a'), check if it's less than 0, and if it is add it to 26. You can make 'a' in your code into a var that is 'A' or 'a' based on whether it's upper or lower case.

  4. #4
    Registered User L_U_K_E's Avatar
    Join Date
    Apr 2006
    Posts
    106
    I just cant do it i ave tryed reversing my code e.g:
    Code:
    decrypted += ( ( (a[i] + 'a') - (offset + offset2) * (offset3 / offset) + offset2) %26) - 'a';
    But that doesn't do it so i drastically need help with this i am not a complete newb but at crpyt. i am.

  5. #5
    Registered User
    Join Date
    Dec 2004
    Location
    UK
    Posts
    109
    the modulus operator will not work in this case since a % b is a negative number if a is negative (if I recall correctly, but if a % b was always in the range [0, b - 1] simple subtraction should work)

    Anyway since your addition is done in modulus arithmetic
    (a - b) % c should be the same as (a + (c - b)) % c.
    If you use the second expression the result will always be a positive (if b < c) number and thus will work correctly.

    The other solution is to check for negative numbers before the modulus operator is applied and add 26 repeatedly until the number is again positive.

    Remember that an aribtrary shift s is an effective shift of s % c (c = 26 in your case) so the limitation of b < c is in fact irrelevent

    Another note is DON'T USE THIS TO ENCRYPT IMPORTANT STUFF. A Caesar code can be broken by stunned chimpmunk high on morphine. Really it is that easy to break so don't use it for anything but toying around. (If you knew this already please ignore me, but since you said you were just starting with cryptography I thout it best to warn you)

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Break it down like prelude said (no one listens anymore)

    Code:
    for (int i = 0; i < b; ++i)
    {
        int ch = a[i];
        ch = ch + 1;
        ch = ch % 26;
        ch = ch + 'a';
        ciphertext += ch;
    }
    Now write the decrypt function for this as well.

    Then refine BOTH at the same time, by adding your next step in the calculation to both sides and checking that it still works.

    You'll also find it a hell of a lot easier to step through using the debugger rather than having "BOOM" the answer in one single statement, but you still being as clueless as ever as to what actually happened.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User L_U_K_E's Avatar
    Join Date
    Apr 2006
    Posts
    106
    I know that the caeser cipher is incredibaly easy to crack for anyone that knows how to however i am just using it as something to start on as i have aways been really interested in cryptography and have always wanted to be able to do it.So this is where i begin (I hope).

    I still cant get the hand of this though i have tried loads of different things and thinking of how i could do it but i just cant i was wondering if i post a section of code could someone tell me how to reverse it as remember i am fairly new to this so i dont really understand anything you lot are saying(lol).

    Code:
    for (int i = 0; i < b; ++i)
    {
       ciphertext += ( ( (a[i] - 'a') + (offset - offset2) / (offset3 * offset) - offset2) %26) + 'a';
    }
    cout<< ciphertext <<endl;
    Thanx for all of your help on this and i am sorry that i dont understand.
    Last edited by L_U_K_E; 06-27-2006 at 10:43 AM.

  8. #8
    Registered User
    Join Date
    Dec 2004
    Location
    UK
    Posts
    109
    Ok, let's try this again, step by step.

    Any caesar cypher performs a transformation
    Code:
    cryptchar = (plainchar + shift) % alphabet_size
    the inverse of this transformation is
    Code:
    plainchar = (cryptchar - shift) % alphabet_size
    since the we are working with ASCII encoded characters we need to shift the origin from 0 to a before the transformation and back to 0 afterwards
    Code:
    plainchar = plainchar1 - 'a' // shift origin to a
    cryptchar = (plainchar + shift) % alphabet_size
    cryptchar1 = cryptchar + 'a' // shift origin back to 0
    So far it's all really simple. The tricky bit is due to c++ implementation of the % operator. Usually modulus operations have range [0, n-1]. The c++ % operator has range [0, n-1] for positive input (the a in a % b) and [-n+1, 0] for negative input.
    This is not an issue in the encryption since plainchar + shift is always positive (if the shift is positive, I'll show later that restricting the shift to the range [0, alphabet_size-1] still gives all possible shifts).
    On the other hand on the decryption step there might be problems. If shift > cryptchar1 then cryptchar - shift will be a negative number which will give you a final result that is out of the intended range.
    To solve this problem you need to ensure that cryptchar1 - shift is never negative.
    One solution is to repeatedly add alphabet_size to the result untile the result is positive (since you are working in modulus arithmetic adding an integer multiple of alphabet_size doesn't change the final result).
    The other soultion is to recognize the fact that (a - b) % c = (a + c - b) % c (remember adding any integer multiple of c doesn't change the result)
    Thus the decryption routine can be written as
    Code:
    plainchar = (cryptchar + alphabet_size - shift) % alphabet_size
    alphabet_size - shift is never negative as long as shift < alphabet_size

    Why do you only need shifts in the range [0, alphabet_size - 1]?
    Assume we have a bad_shift that is outside that range. We can break down bad shift into
    Code:
    bad_shift = a * alphabet_size + shift
    where a is an arbitrary integer and 0 <= shift < alphabet_size.
    Since we are working in modulus arithmetic the a * alphabet_size component has no effect to the final reusult and we can safely ignore it.

    Hope this helps

    PS

    Quote Originally Posted by L_U_K_E
    Code:
       ciphertext += ( ( (a[i] - 'a') + (offset - offset2) / (offset3 * offset) - offset2) %26) + 'a';
    I hope you realise that all those calculations with the 3 offsets could be done once and stored in a single variable
    Last edited by sigfriedmcwild; 06-27-2006 at 02:27 PM.

  9. #9
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by sigfriedmcwild
    Hope this helps
    It won't, I'm afraid. Not untill Luke understands he needs to actually read the answers.

    Is there a FAQ for these things? Something like, "Should I read the answers to my Post?"...
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  10. #10
    Registered User
    Join Date
    Dec 2004
    Location
    UK
    Posts
    109
    Oh well...
    On a slightly different topic, can anyone explain why c++ (and I guess c originally) use such an obtuse implementation of the % operator?

  11. #11
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    The output of the modulos operator is machine-dependent if one of the operands is negative and another is positive. In fact both the result and the sign of the result are machine-dependent. This is not a C++ thing. But instead the way different machines deal with arithmetics.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  12. #12
    Registered User
    Join Date
    Mar 2006
    Posts
    725
    I guess on modern platforms all the basic operators +-*/%=&|^~ just call the processor to do it for you. That's a Good Thing, you know.

    And LUKE, for more cryptography go brush up on math, especially on number theory. If you have some dough, get Elementary Number Theory and its Applications, Kenneth H. Rosen.
    Code:
    #include <stdio.h>
    
    void J(char*a){int f,i=0,c='1';for(;a[i]!='0';++i)if(i==81){
    puts(a);return;}for(;c<='9';++c){for(f=0;f<9;++f)if(a[i-i%27+i%9
    /3*3+f/3*9+f%3]==c||a[i%9+f*9]==c||a[i-i%9+f]==c)goto e;a[i]=c;J(a);a[i]
    ='0';e:;}}int main(int c,char**v){int t=0;if(c>1){for(;v[1][
    t];++t);if(t==81){J(v[1]);return 0;}}puts("sudoku [0-9]{81}");return 1;}

  13. #13
    Registered User L_U_K_E's Avatar
    Join Date
    Apr 2006
    Posts
    106
    could someone tell me whats the matter with this please:

    Code:
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
        string cryptchar;
        string plainchar = "luke";
        int shift = 2;
        int alphabet_size = plainchar.length();
        for (int i = 0; i < alphabet_size; ++i)
        {
            cryptchar = (plainchar + shift) %alphabet_size;
            plainchar = (cryptchar - shift) %alphabet_size;
        }
        cout<< "Encrypted: " << cryptchar <<endl;
        cin.get();
        cout<< "Decrypted: " << plainchar <<endl;
        cin.get();
        return 0;
    }
    When i get to the
    Code:
    cryptchar = (plainchar + shift) %alphabet_size;
    bit i just get the message 'no match for operator+ ' in 'plainchar + shift'.Thanks for all your help so far i just hope i can get the hang of it.

    P.S Thanx loads Sigfried for all of your help and patience with me(lol).

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    plainchar is a string, shift is an int. Perhaps you want to use plainchar[i] instead.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User L_U_K_E's Avatar
    Join Date
    Apr 2006
    Posts
    106
    I changed but alli get is 1 little heart on the encrypted part and decrypted = 1 little smily face!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Simple Cipher Program
    By PunchOut in forum C Programming
    Replies: 7
    Last Post: 11-22-2008, 01:12 PM
  2. Replies: 16
    Last Post: 11-23-2007, 01:48 PM
  3. About aes
    By gumit in forum C Programming
    Replies: 13
    Last Post: 10-24-2006, 03:42 PM
  4. My little Caesar cipher emulator
    By dead_cell in forum C++ Programming
    Replies: 3
    Last Post: 01-16-2004, 01:05 AM