• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1436
  • Last Modified:

ATABSH ALGORITHM

I am interested in writing a program to de-encrypt message using the Atbash cipher.  I understand the principle of it but what kind of algorithm should I use to write the program.  THe goal is to convert a given message(encrypted) into plain text.  I would like to use this for ASCII characters as well as letters.  Again I am just looking for for the program flow not necessarily the code itself.
0
jholmes9186
Asked:
jholmes9186
  • 10
  • 5
  • 4
  • +1
3 Solutions
 
millsoftCommented:

1. Ask user for password.
2. Hash password to create key.
3. read message
4. encrypt/decrypt as appropriate with key created in step 2.
5. write clear/crypto text to file/screen as desired.
0
 
millsoftCommented:
If you want just to decrypt messages and you have a source of the key, then skip steps 1 & 2.
0
 
millsoftCommented:

Hi J,

I didn't realize atbash was a substitution cipher with a single key.  Essentially there is no key to generate.

http://www.murky.org/cryptography/classical/atbash.shtml

As for the code, I'd create an array that given an input character (in ASCII code), the element at that position of the array is the clear text associated with that cipher letter.

For example, A = ascii 65.

So Key[65] = Z  (in the case where A is the cipher text of Z).

Brad  
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
millsoftCommented:
ANother implementation option for atbash, if you want a strict reverse ordering:

cleartext = (unsigned char) 255 - (unsigned char) ciphertext;

0
 
PaulCaswellCommented:
I'd suggest that the core of the concversion would be:

message[i] = 'Z'-(message[i]-'A');

This sets the character to its atbash encrypted form.

Obviously, you'd have to do somethiong like:

if ( 'a' <= message[i] && message[i] <= 'z' )
{
 message[i] = 'z'-(message[i]-'a');
}
else if ( 'A' <= message[i] && message[i] <= 'Z' )
{
 message[i] = 'Z'-(message[i]-'A');
}

I am sure you can take this to where you want to go.

Paul
0
 
jholmes9186Author Commented:
If I write this program to convert the ASCII characters it should also convert alpha characters, correct?
0
 
millsoftCommented:
jholmes9186,

The formula I gave (255 - ciphertext) will reverse all of the primary 256 ASCII values  without needing to worry about if statements, so yes it should work on any file.
Brad
0
 
jholmes9186Author Commented:
Thank you Brad.  Can you give me a quick example on how to write this into a function (for instance abcde becomes zyxwvu).  I believe I understand the logic but not the implmentation.
0
 
PaulCaswellCommented:
The problem is that the non-alpha characters do not have a 'predictable' encoding. The only defined encoding is for ASCII. I would suggest you stick to just alpha.

Paul.
0
 
millsoftCommented:
Hi jholmes,

what language?

Here it is in VisualBasic

public Function AtBashString( sClear as string ) as string

dim sOut as string
dim i as integer
for i = 1 to len( sClear )
    sOut = sOut & chr( 255 - asc( mid(sClear , i , 1) ) )
next
AtBashString = sOut

end function
0
 
PaulCaswellCommented:
I'd suggest you do a Google for Atbash. Its neither ASCII based nor Alpha based. It was originally designed for hebrew text so even my solution would be faulty. Just using 255-'x' would be even further from correct.

Paul
0
 
jholmes9186Author Commented:
The language is C. I understand the history behind Atbash (hiding certain powerful names for God).  However the idea is to be able to read an "encrypted" input file of ASCII or alpha and convert it.  That is why I was asking about Brads solution above.  My thought was that if it converted ASCII it should convert alpha as well.
0
 
PaulCaswellCommented:
>>My thought was that if it converted ASCII it should convert alpha as well.

It wont! Ascii alphabetic characters have code < 128. Using 'chr( 255 - asc( mid(sClear , i , 1) ) )' (or the C equivalent) they will all be converted to some code > 128 which is not alphanumeric. Besides, ASCII is only defined for characters < 128.

Paul
0
 
millsoftCommented:
I respectfully disagree with Paul as follows.

The trademark of atbash is that it takes the alphabet (whatever alphabet you happen to be using) and performs a substitution cipher with the alphabet against it's reverse.

My implementation does exactly that taking alphabet to be the 256 character 'alphabet' consisting of all possible values of a byte (0-255).

If you were to be using a 7-bit ASCII alphabet, then you would use 127 as the baseline value in my code (rather than 255), but it would be otherwise the same.  I just see no reason to make limit the implementation to 7 bits when 8-bit files are the current standard.

Therefore, while my implementation is not true atbash (since it doesn't actually use the hebrew alphabet), it will work on any ASCII file, or indeed any binary file of any sort.

Brad

0
 
millsoftCommented:

/*
   C implementation of Atabsh cipher for a BYTE array.  
   Modifies data inplace (if you want to save the input data, make a copy first)
   since the same function is used for encryption & decryption, the input data may have NULL characters in it
   so the function takes buffer length.
*/
void Atabsh( unsigned char* pStr, int nDataLen )
{
   for ( int i = 0; i < nDataLen; i++, pStr++ )
   {
      *pStr = ( 255 - *pStr );
   }
}
0
 
jholmes9186Author Commented:
Thanks to the advice given I have figured out the program.  The code written below is my final program.  Two things that I am still interested in however:
(1)  How can I make it do the same thing without so much code.  and
(2)  Why will the atbash 2 function not translate my first file which is solely an alpha substitution.  Based on the discussion earlier I thought that the atbash2 function should decode any message wrtten in using characters on the ASCII table.  Any last help and/or answers would be appreciated before I close the question.


#include <stdio.h>  
#include <stdlib.h>
#include <string.h>

#define LENGTH 100
#define FILENAME1 "pgm7w04msg1.txt"
#define FILENAME2 "pgm7w04msg2.txt"

void atbash(char *in, char* out);
void atbash2(char *in, char *out);

void atbash(char *in, char* out){

      int i,stringlength;

      stringlength=strlen(in);

      for (i=0;i<=stringlength;i++){

      if (in[i]>='a' && in[i] <='z') in[i]-=32;  /*Is there a quicker way to force upper characters, I tried isupper but the copiler did not recognize it. */

      if (in[i]>='A' && in[i] <='Z') out[i]=155-in[i];

      else out[i] = in [i];
      
      }
}

void atbash2(char *in, char *out){

      int i, stringlength;
      
      stringlength=strlen(in);
      
      for (i=0; i<stringlength;++i){

      if (in[i]>=' ' && in[i] <='~') out[i]= 126-in[i];
      
      else out[i]=in[i];
      
      }
}


int main(void) {

      int i=1;

      char in[LENGTH], out[LENGTH];
      
      char filename[]="FILENAME1";
      
      FILE*fp1;
      
      FILE*fp2;
      
      fp1 = fopen(FILENAME1, "r");
      
      if (fp1==NULL){
            
            printf("\n\n File is not found in current directory.\n\nPush return to end.", FILENAME1);
      
            exit(1);
      }
      
      printf("Translating file %s\n\n",FILENAME1);
      
      while (fgets(in,LENGTH,fp1)!=NULL){
      
            atbash (in,out);
            
            printf("%s",out);
            }
      
      fclose (fp1);
      
      fp2 = fopen(FILENAME2, "r");
      
      if (fp2==NULL){
            
            printf("\n File is not found in current directory.\n\nPush return to end.", FILENAME2);
      
            exit(1);
      }
      
      printf("\n\nTranslating file %s\n\n",FILENAME2);
      
      while (fgets(in,LENGTH,fp1)!=NULL){
      
            atbash2 (in,out);
            
            printf("%s",out);
            }
      
      fclose (fp2);
      
            
      return 0;
}

0
 
millsoftCommented:
jHolmes,  can you post the file that ATABSH2 doesn't deal with correctly?

It may be 126 should perhaps be 127.

Brad
0
 
jholmes9186Author Commented:
Brad,

Here is the file I am trying to decipher.  By the way, if you change the number to 158 it reads out text legibly but has a lot of extra stuff in the file.  I don't know if it is suposed to be there or not.

J65+~19++=79~+6/)2:~50;2):9~.)0;*)=*5/0r~2/'9,
=0:~)..9,~;=+9r~=0:~0)1<9,+~2539~mlkjihgfenp~V9,9
=,9~*69~+%1</2+~=</(9~*69~0)1<9,~39%+r~}^{zy@xtvup
K/19~/*69,~+%1</2+~=,9~<,=;9+r~#!r~<,=;39*+~CAr
7,9=*9,o29++~*6=0r~b`r~+915;/2/0rcr~+50729r~wr~=0:
:/)<29r~|r~-)/*9+r~=0:~-)9+*5/0~1=,3r~_p

0
 
millsoftCommented:
Hi JH,

The atabsh2 function had two errors;  First, the wrong base, as you indicated.  The decryption needed to start at 158.  Second, the output buffer was not terminated at the end of the function, so any garbage characters left behind from previous calls/uses of the output buffer were left behind.

Here is the revised function:

void atbash2(char *in, char *out)
{

      int i, stringlength;

      stringlength=strlen(in);

      for (i=0; i<stringlength;++i)
      {
            if (in[i]>=' ' && in[i] <='~')
                  out[i]= 158-in[i];
            else
                  out[i]=in[i];
      }
      out[i]=0; // terminate output buffer!
}

0
 
Daniel JungesCommented:
or this one 'for decryptions':

         char* text = ...
      char* cipherText = ...
      int size = strlen(text);
      for(int i=0; i<size; i++){
            if(isalpha(text[i]) == false){
                  cipherText[i] = text[i];
                  continue;
            }
            cipherText[i] = (islower(text[i]) ? 'a'+'z'-text[i] : 'A'+'Z'-text[i]);
      }
0
 
Daniel JungesCommented:

opps, please consider renamed "text" -> "cipherText" and "cipherText" -> "text"
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 10
  • 5
  • 4
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now