Tuesday, March 27, 2012

Disk Cipher Algorithms in C

The disk cipher is a combination of the Caesar Cipher and the Simple Substitution Cipher. It resembles  the Simple Substitution Cipher because it uses two predefined alphabets and it resembles the Caesar Cipher because the substitution is done according to a predefined shift.

Learn more about the Caesar Cipher.
Learn more about the Simple Substitution Cipher.

If you want to read more about the history of the disk cipher, you can check out  this article.

In order to implement the algorithm in C, we shall use the following enumeration who shall reflect if an encoding/decoding operation was completed correctly.
typedef enum
{
 OPERATION_SUCCESS = 1U,
 OPERATION_FAILED = 0U,
}OPERATION_STATUS;
1.The Encoding Algorithm

The encoding algorithm is very similar to the one used for the Simple Substitution Cipher, except that the shift will be added to the position (and a modulo operation shall be used in order to avoid overflow).  In order to obtain the position of the encoded symbol, the following formula shall be used:
where:
  • j - the position of the symbol in the cipher text (coded alphabet)
  • Ei - the position of the symbol from the original message in the original alphabet (plain text)
  • s - the shift value
  • O - the original alphabet
OPERATION_STATUS DiskCipher_Encode(char* originalAlphabet,
                                   char* codedAlphabet,
                                   char* originalMessage,
                                   char* encodedMessage,
                                   unsigned short shift)
{
 unsigned short alphabetLength = strlen(originalAlphabet);
 unsigned int messageLength    = strlen(originalMessage);
 unsigned int i = 0U;
 char* pointer = NULL;
 unsigned int position = 0U;
 if( alphabetLength != strlen(codedAlphabet) )
 {
  //The lengths of the alphabets do not match
  return OPERATION_FAILED;
 }
 for(i=0; i<messageLength; i++)
 {
  pointer  = strchr(originalAlphabet, originalMessage[i]);
  if(pointer==NULL)
  {
   //A character in the message was not found in the
   //original alphabet
   return OPERATION_FAILED;
  }
  else
  {
   position = ((pointer - originalAlphabet) + shift)%alphabetLength;
   encodedMessage[i] = codedAlphabet[position];
  }
 }
 encodedMessage[messageLength] = '\0';
 return OPERATION_SUCCESS;
}
The function receives 5 parameters:
  • originalAlphabet - a pointer to a string containing the plain text alphabet (who has all the letters that appear in the originalMessage). All symbols in the originalAlphabet should appear only once.
  • codedAlphabet - a pointer to a string containing the cipher text alphabet (who has the same length as the originalAlphabet string). All symbols in the codedAlphabet should appear only once.
  • originalMessage - a pointer to a string containing the message who will be encoded
  • codedMessage - a pointer to a pre-allocated empty string who will contain the encoded message.
  • shift - what is the offset value used for the substitution
The function returns OPERATIONS_SUCCES if all preconditions have been respected, respectively OPERATON_FAILED if the lengths of the alphabets are different or if the function found a symbol in the original message who has not been defined in the originalAlphabet.

2.The Decoding Algorithm

The decoding algorithm shall do the inverse operation of encoding. Instead of adding the shift, the shift will be subtracted. In order to obtain the position of the decoded symbol, the following formula shall be used:
where:
                                       
  • j - the position of decoded symbol in the plain text (original Alphabet)
  • Ci - the position of the symbol from the encoded message in the cipher text (coded alphabet)
  • s - the shift value
  • O - the length of the original alphabet
OPERATION_STATUS DiskCipher_Decode(char* originalAlphabet,
                                   char* codedAlphabet,
                                   char* encodedMessage,
                                   char* decodedMessage,
                                   unsigned short shift)
{
 unsigned short alphabetLength = strlen(originalAlphabet);
 unsigned int messageLength    = strlen(encodedMessage);
 unsigned int i = 0U;
 char* pointer = NULL;
 unsigned int position = 0U;
 if( alphabetLength != strlen(codedAlphabet) )
 {
  //The lengths of the alphabets do not match
  return OPERATION_FAILED;
 }
 for(i=0; i<messageLength; i++)
 {
  pointer  = strchr(codedAlphabet, encodedMessage[i]);
  if(pointer==NULL)
  {
   //A character in the message was not found in the
   //coded alphabet
   return OPERATION_FAILED;
  }
  else
  {
   position = (abs(alphabetLength + (pointer - codedAlphabet) - shift))
      %alphabetLength;
   decodedMessage[i] = originalAlphabet[position];
  }
 }
 decodedMessage[messageLength] = '\0';
 return OPERATION_SUCCESS;
}
The function receives 5 parameters:
  • originalAlphabet - a pointer to a string containing the plain text alphabet (who has all the letters that appear in the originalMessage). All symbols in the originalAlphabet should appear only once.
  • codedAlphabet - a pointer to a string containing the cipher text alphabet (who has the same length as the originalAlphabet string). All symbols in the codedAlphabet should appear only once.
  • encodedMessage - a pointer to a string containing the message who will be encoded
  • decodedMessage - a pointer to a pre-allocated empty string who will contain the decoded message.
  • shift - what is the offset value used for the substitution
The function returns OPERATIONS_SUCCES if all preconditions have been respected, respectively OPERATON_FAILED if the lengths of the alphabets are different or if the function found a symbol in the encoded message who has not been defined in the coded Alphabet.

3.Example
Here's a short example on how to use the functions described above:
char originalAlphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
char codedAlphabet[]    = "QWERTYUIOPASDFGHJKLZXCVBNM#";
char originalMessage[]  = "DISK CIPHER";
char encodedMessage[12];
char decodedMessage[12];
unsigned int shift = 15;
DiskCipher_Encode(originalAlphabet, codedAlphabet,
    originalMessage, encodedMessage,shift);
puts(encodedMessage);
DiskCipher_Decode(originalAlphabet, codedAlphabet,
    encodedMessage, decodedMessage,shift);
puts(decodedMessage);

No comments:

Post a Comment

Got a question regarding something in the article? Leave me a comment and I will get back at you as soon as I can!

Related Posts Plugin for WordPress, Blogger...
Recommended Post Slide Out For Blogger