Solved

# ATABSH ALGORITHM

Posted on 2004-08-04
1,354 Views
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
Question by:jholmes9186
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 10
• 5
• 4
• +1

LVL 5

Expert Comment

ID: 11716693

2. Hash password to create key.
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

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

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).

0

LVL 5

Expert Comment

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

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

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

LVL 5

Expert Comment

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.
0

Author Comment

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

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

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

LVL 16

Expert Comment

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

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

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

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.

0

LVL 5

Expert Comment

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

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){

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){

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

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

It may be 126 should perhaps be 127.

0

Author Comment

ID: 11733138

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

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

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

ID: 11736040

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

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

### Suggested Solutions

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were smallâ€¦
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and infâ€¦
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 opening and reading files in the C programming language.
###### Suggested Courses
Course of the Month6 days, 19 hours left to enroll