0

I am trying to decrypt a monoalphabetic cipher. I read in a text file that is very large. I have the key already which is: A=O, B=M, C=V, D=H, E=J, F=R, G=T, H=L, I=Y, J=A, K=C, L=K, M=X, N=E, O=W, P=U, Q=B,R=G, S=S, T=Q, U=F, V=N, W=Z, X=I, Y=P, Z=D.

I am not sure how to go about replacing the letters and outputting it to a new text file. Right now the text file is just printing on the console with nothing being done to it.

I have read in the text file character by character.

#include<fstream>
#include<iostream>
#include<string>

using namespace std;

int main()
{
   ifstream input("cipher.txt");
   char data;
   while(!input.eof()){

     input.get(data);
     cout<<data;
   }
     cout<<endl;
     input.close();
}
jmf24
  • 11
  • 2

2 Answers2

2

I must admit that, at first, I didn't carefully read OPs question.

Encoding a range from A to Z, a std::map<> (as suggested in P.Ws answer) is able to do it but seems to me a bit over-engineered. An array is fine to do this job as well and surely faster. (Access is O(1) instead of O(ld(N)).)

So, encoding could look like this:

char encode(char c)
{
  static const char cMap[] = {
    /* A= */ 'O',
    /* B= */ 'M',
    /* C= */ 'V',
    /* D= */ 'H',
    /* E= */ 'J',
    /* F= */ 'R',
    /* G= */ 'T',
    /* H= */ 'L',
    /* I= */ 'Y',
    /* J= */ 'A',
    /* K= */ 'C',
    /* L= */ 'K',
    /* M= */ 'X',
    /* N= */ 'E',
    /* O= */ 'W',
    /* P= */ 'U',
    /* Q= */ 'B',
    /* R= */ 'G',
    /* S= */ 'S',
    /* T= */ 'Q',
    /* U= */ 'F',
    /* V= */ 'N',
    /* W= */ 'Z',
    /* X= */ 'I',
    /* Y= */ 'P',
    /* Z= */ 'D'
  };
  return c >= 'A' && c <= 'Z'
    ? cMap[c - 'A'] // range ['A', 'Z'] to range [0, 25]
    : '?';
}

Reading twice, I realized the decrypt – oops.

However, it does work as well in reverse direction:

char decode(char c)
{
  static const char cMap[] = {
    /* A= */ 'J',
    /* B= */ 'Q',
    /* C= */ 'K',
    /* D= */ 'Z',
    /* E= */ 'N',
    /* F= */ 'U',
    /* G= */ 'R',
    /* H= */ 'D',
    /* I= */ 'X',
    /* J= */ 'E',
    /* K= */ 'L',
    /* L= */ 'H',
    /* M= */ 'B',
    /* N= */ 'V',
    /* O= */ 'A',
    /* P= */ 'Y',
    /* Q= */ 'T',
    /* R= */ 'F',
    /* S= */ 'S',
    /* T= */ 'G',
    /* U= */ 'P',
    /* V= */ 'C',
    /* W= */ 'O',
    /* X= */ 'M',
    /* Y= */ 'I',
    /* Z= */ 'W'
  };
  return c >= 'A' && c <= 'Z'
    ? cMap[c - 'A'] // range ['A', 'Z'] to range [0, 25]
    : '?';
}

The re-ordering of array values was a bit tedious – I could've done it using sort.

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56
1
  • Define a std::map<char, char> where you store the alphabet and its key
  • Open a new file "Deciphered.txt" in write mode
  • As you read each char from the file, find its value from the map and write into the new file.

Also read why-is-while-feof-file-always-wrong for the correct way to read data from a file.

P.W
  • 26,289
  • 6
  • 39
  • 76