Woldev
Woldev

Reputation: 93

What is the best way to decode a message given a hash function

I have a .txt file that has an encoded message, to decodde it you have to switch specific characters to a character in the alphabet. (It's like a letter x pointing to the letter y) then use it to decode the message from the .txt file. I have the alphabet stored in a c-string:

const int ALPHA_SIZE = 26;

char alphabet[ALPHA_SIZE] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
    'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
    'y', 'z' };

Then respectivelly the letters that correspond to the alphabet

char hashFunc[ALPHA_SIZE] = {'i', 'z', 't', 'o', 'h', 'n', 'd', 'b', 'e', 'q', 'r', 'k',
    'g', 'l', 'm', 'a', 'c', 's', 'v', 'w', 'f', 'u', 'y', 'p', 'x'};

Now, my text file has this:

ifqkwxcadf ar cei fpoi masif cd cei xkdqirr du pxxnwafm pf pnmdkaceo cd p oirrpmi, teaqe rqkpohnir cei gpcp af ac-oplafm ac sikw gauuaqvnc pfg caoi qdfrvoafm, au fdc xkpqcaqpnnw aoxdrrahni, cd gigvqi cei dkamafpn masif dfnw cei ifqdgig gpcp. afxvcr cd cei pnmdkaceo cwxaqpnnw afsdnsi pggacadfpn riqkic gpcp qpnnig liwr, teaqe xkisifcr cei oirrpmi ukdo hiafm giqdgig-isif au cei pnmdkaceo ar xvhnaqnw lfdtf.

How do I correlate these 3 to give me the decoded message? I was thinking through switch statement but I'm sure there's other way more efficient than this. Thank you.

Upvotes: 2

Views: 556

Answers (2)

aaaaaa123456789
aaaaaa123456789

Reputation: 5842

Disclaimer: I'm not a C++ programmer; I'm a C programmer. But this answer will work for both C and C++.

Instead of using array notation (i.e., with braces) for initializing your arrays, you should use actual C strings. That is:

char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
char hashFunc[] = "iztohndbeqrkglmacsvwfuypxj";

(Your original hashFunc was missing j; I assume that's a transcription error. I added it at the end.)

This way, you can easily convert from one "alphabet" to the other:

void convert_alphabets (char * str, const char * from, const char * to) {
  const char * found;
  while (*str) {
    found = strchr(from, *str);
    if (found)
      *str = to[found - from];
    str ++;
  }
}

(You'll need to include <string.h> to get strchr(), or <cstring> in C++ if you prefer the std:: namespaced version.)

This function merely looks up every character in the from string, and if it finds it, replaces it with the equivalent character in the to string (notice that found will point to the position where the character was found, and thus found - from will give you the index into the from string/array). You can call it with from = alphabet and to = hashFunc to encode, or vice-versa to decode.

Upvotes: 1

paddy
paddy

Reputation: 63471

I always red-flag any question from a beginner programmer asking for "the best" way to do something.

But I am answering because a switch is definitely inappropriate for this, due to the amount of effort required to code it, and how annoyed I would be to encounter any code based on that approach.

The fact is, your problem is simply one of mapping. All you are doing is mapping one character to another. So just build a table. If you are on 99.9999% of modern computers, you'll be dealing with 8-bit characters (we should ignore UTF-8, but actually this will be compatible with UTF-8 too).

char encode[256], decode[256];
for (int i = 0; i < 256; i++) encode[i] = decode[i] = (char)i;
for (int i = 0; i < ALPHA_SIZE; i++) {
    encode[(unsigned char)alphabet[i]] = hashFunc[i];
    decode[(unsigned char)hashFunc[i]] = alphabet[i];
}

From there it should be obvious. All you need to do to encode or decode a character is to use that character's (unsigned) value to look up the corresponding table entry.

This method is probably the fastest basic approach. But it might not be the best for whatever your requirements are.

Upvotes: 4

Related Questions