Solved

ATABSH ALGORITHM

Posted on 2004-08-04
21
1,314 Views
Last Modified: 2010-08-05
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
Comment
Question by:jholmes9186
  • 10
  • 5
  • 4
  • +1
21 Comments
 
LVL 5

Expert Comment

by:millsoft
ID: 11716693

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
 
LVL 5

Expert Comment

by:millsoft
ID: 11716705
If you want just to decrypt messages and you have a source of the key, then skip steps 1 & 2.
0
 
LVL 5

Expert Comment

by:millsoft
ID: 11716796

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
 
LVL 5

Expert Comment

by:millsoft
ID: 11717053
ANother implementation option for atbash, if you want a strict reverse ordering:

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

0
 
LVL 16

Accepted Solution

by:
PaulCaswell earned 100 total points
ID: 11717144
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
 

Author Comment

by:jholmes9186
ID: 11718463
If I write this program to convert the ASCII characters it should also convert alpha characters, correct?
0
 
LVL 5

Expert Comment

by:millsoft
ID: 11721560
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
 

Author Comment

by:jholmes9186
ID: 11722117
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
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 11723947
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
 
LVL 5

Expert Comment

by:millsoft
ID: 11726399
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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 16

Expert Comment

by:PaulCaswell
ID: 11726567
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
 

Author Comment

by:jholmes9186
ID: 11726935
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
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 11727013
>>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
 
LVL 5

Expert Comment

by:millsoft
ID: 11728065
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
 
LVL 5

Expert Comment

by:millsoft
ID: 11728194

/*
   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
 

Author Comment

by:jholmes9186
ID: 11731937
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
 
LVL 5

Expert Comment

by:millsoft
ID: 11733115
jHolmes,  can you post the file that ATABSH2 doesn't deal with correctly?

It may be 126 should perhaps be 127.

Brad
0
 

Author Comment

by:jholmes9186
ID: 11733138
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
 
LVL 5

Assisted Solution

by:millsoft
millsoft earned 200 total points
ID: 11734005
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
 
LVL 14

Assisted Solution

by:Daniel Junges
Daniel Junges earned 50 total points
ID: 11735978
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
 
LVL 14

Expert Comment

by:Daniel Junges
ID: 11736040

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

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
scanf and assignment suppression 13 143
posix semaphore deadlock 13 108
Binary Bomb: Phase 4 func4 3 282
c language help - file paths 7 113
Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now