개발자 톡

연습문제 톡 [HSAT 3회 정기 코딩 인증평가 기출] 플레이페어 암호

c++답

등록일
2024-10-03 15:14:47
조회수
103
작성자
jshch13

#include <bits/stdc++.h>

using namespace std;


string msg, key;

int visited[26];

char p[5][5]; // 5x5 테이블


// 5x5 테이블을 생성하는 함수

void createTable(const string& key) {

  int r = 0, c = 0;

  for (int i = 0; i < key.size(); i++) {

    int temp = key[i] - 'A';

    if (visited[temp]) continue; // 이미 사용된 문자 건너뛰기

    visited[temp] = 1;

    p[r][c] = key[i];

    c++;

    if (c == 5) { r++; c = 0; } // 행을 다 채웠으면 다음 행으로

  }

   

  // 나머지 알파벳 채우기 (I와 J는 같은 것으로 취급)

  for (char ch = 'A'; ch <= 'Z'; ch++) {

    if (!visited[ch - 'A'] && ch != 'J') { // J는 제외

      p[r][c] = ch;

      c++;

      if (c == 5) { r++; c = 0; }

    }

  }

}


// 메시지를 두 글자씩 나누고 쌍을 맞추는 함수

string preprocessMessage(string msg) {

  string new_msg = "";

  new_msg += msg[0];

  char pre = msg[0];

  for (int i = 1; i < msg.size(); i++) {

    if (msg[i] == pre && new_msg.size() % 2) {

      if (pre == 'X') new_msg += "Q"; // 쌍이 XX이면 Q 추가

      else new_msg += "X"; // 나머지는 X로 쌍을 맞춤

    }

    new_msg += msg[i];

    pre = msg[i];

  }

  if (new_msg.size() % 2) new_msg += "X"; // 홀수 글자가 남으면 X 추가

  return new_msg;

}


// 두 글자를 암호화하는 함수

string encryptPair(const string& a, map<char, pair<int, int>>& pos) {

  char ch1 = a[0], ch2 = a[1];

  int r1 = pos[ch1].first, c1 = pos[ch1].second;

  int r2 = pos[ch2].first, c2 = pos[ch2].second;

   

  if (r1 == r2) {

    // 같은 행에 있을 때

    return string(1, p[r1][(c1 + 1) % 5]) + p[r2][(c2 + 1) % 5];

  } else if (c1 == c2) {

    // 같은 열에 있을 때

    return string(1, p[(r1 + 1) % 5][c1]) + p[(r2 + 1) % 5][c2];

  } else {

    // 서로 다른 행, 열에 있을 때

    return string(1, p[r1][c2]) + p[r2][c1];

  }

}


// 암호화된 메시지를 생성하는 함수

string encryptMessage(const string& message, map<char, pair<int, int>>& pos) {

  string ret = "";

  for (int i = 0; i < message.size(); i += 2) {

    string pair = message.substr(i, 2);

    ret += encryptPair(pair, pos); // 두 글자씩 암호화

  }

  return ret;

}


int main() {

  // 입력받기

  cin >> msg >> key;

   

  // 5x5 테이블을 생성하고 각 알파벳의 위치 저장

  createTable(key);

   

  // 각 알파벳의 위치를 저장할 맵 (위치 정보는 {row, col})

  map<char, pair<int, int>> pos;

  for (int i = 0; i < 5; i++) {

    for (int j = 0; j < 5; j++) {

      pos[p[i][j]] = {i, j}; // 각 문자의 위치 저장

    }

  }

   

  // 메시지 전처리

  string preparedMessage = preprocessMessage(msg);

   

  // 암호화된 메시지 생성

  string encryptedMessage = encryptMessage(preparedMessage, pos);

   

  // 결과 출력

  cout << encryptedMessage << endl;

   

  return 0;

}


#[HSAT_3회_정기_코딩_인증평가_기출]_플레이페어_암호

이 카테고리의 톡 더보기