Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

랜덤 치환 암호 연구소

보안팀에서 “사내 채팅 로그를 외부로 공유할 때, 원문을 그대로 노출하지 않으면서도 복호화 가능한 형태로 바꾸는 도구”를 만들기로 했습니다.
이 도구는 입력 문장을 랜덤 치환(Substitution) 암호로 변환하고, 같은 키로 복호화 검증까지 수행합니다.

이번 미션은 아래 요구사항에 맞게 치환 키 생성, 암호화/복호화, 통계 리포트 출력을 구현하는 것입니다.


테스트 실행 가이드

  • 터미널에서 java -version을 실행하여 Java 버전이 21인지 확인한다.
  • Mac 또는 Linux 사용자는 ./gradlew clean test 명령을 실행한다.
  • Windows 사용자는 gradlew.bat clean test 또는 ./gradlew.bat clean test 명령을 실행한다.

과제 진행 요구 사항

  • 기능을 구현하기 전 README.md에 구현할 기능 목록을 정리해 추가한다.
  • Git의 커밋 단위는 README.md에 정리한 기능 목록 단위로 추가한다.
  • 커밋 메시지는 AngularJS Commit Message Conventions을 참고해 작성한다.

기능 요구 사항

프로그램을 실행하면 아래 순서대로 입력을 받는다.

  1. 원문 메시지 입력
  2. 알파벳 처리 모드 입력
  3. 숫자 처리 모드 입력
  4. 키 미리보기 출력 개수 입력
  5. 랜덤 치환 키 생성
  6. 암호문/리포트 출력 + 복호화 검증 출력 후 종료

입력 요구 사항

1) 원문 메시지

  • 1~200자
  • 허용 문자
    • 영문 대소문자: A-Z, a-z
    • 숫자: 0-9
    • 공백: space 한 칸
    • 구두점: . , ! ?
  • 위 허용 문자 외의 문자가 포함되면 예외 처리한다.

2) 알파벳 처리 모드

  • E : 대소문자 구분(Extend)
    • A-ZA-Z 범위 안에서 치환
    • a-za-z 범위 안에서 치환
  • I : 대소문자 미구분(Insensitive)
    • 입력 메시지의 모든 영문은 소문자로 통일한 뒤 치환한다.
    • 출력 암호문도 영문은 모두 소문자로 출력한다.

3) 숫자 처리 모드

  • K : 숫자 유지(Keep) — 0-9는 그대로 둔다.
  • S : 숫자 치환(Substitute) — 0-9도 랜덤 치환 키를 만들어 치환한다.

4) 키 미리보기 출력 개수

  • 5~20 사이의 정수
  • 암호문 출력 후, 치환 키의 일부를 “미리보기”로 출력한다.
  • 미리보기는 원본 문자 기준 오름차순으로 정렬하여 앞에서부터 N개를 출력한다.

랜덤 치환 키 생성 규칙

  • 반드시 camp.nextstep.edu.missionutils.Randoms.pickNumberInRange()를 사용하여 랜덤 값을 생성한다.
  • 치환은 중복 없이 1:1로 매핑되어야 한다(순열).
  • 알파벳 처리 모드에 따라 키의 대상이 달라진다.

모드별 키 대상

  • E (대소문자 구분)
    • 대문자 키: A-Z (26개)
    • 소문자 키: a-z (26개)
  • I (대소문자 미구분)
    • 소문자 키: a-z (26개)
      (입력 영문을 소문자로 통일하기 때문에 대문자 키는 생성하지 않는다.)

숫자 처리 모드가 S라면 숫자 키도 생성한다.

  • 숫자 키: 0-9 (10개)

출력 요구 사항

1) 암호문 출력

  • 아래 형식으로 출력한다.
암호화를 시작합니다.
암호문: <cipherText>
체크섬: <checksum>

체크섬 계산

  • 암호문에서 공백(space)을 제외한 모든 문자의 ASCII 코드값을 더한 뒤, 10000으로 나눈 나머지
  • 예) checksum = (sum % 10000)

2) 키 미리보기 출력

  • 아래 형식으로 출력한다.
키 미리보기
- A -> Q
- B -> T
...
  • 출력 개수 N만큼만 출력한다. (알파벳은 최대 26개, 숫자는 최대 10개이므로 min(N, 최대개수) 만큼 출력한다.)
  • E 모드에서 대문자/소문자 키를 모두 생성한 경우:
    • 대문자 미리보기 → 소문자 미리보기 → (숫자 모드가 S면) 숫자 미리보기 순서로 출력한다.
  • I 모드에서는 소문자 미리보기만 출력한다(필요 시 숫자 미리보기 추가).

3) 빈도 리포트 출력

  • 암호문에서 공백(space)과 구두점(. , ! ?) 을 제외하고, 가장 많이 등장한 문자 3개를 출력한다.
  • 등장 횟수가 같다면 문자 기준 사전순(오름차순)으로 정렬한다.
  • 아래 형식으로 출력한다.
빈도 리포트 (TOP 3)
1) <char> : <count>
2) <char> : <count>
3) <char> : <count>

4) 복호화 검증 출력

  • 생성된 키로 암호문을 복호화했을 때 원문과 동일하면 OK를 출력한다.
  • 원문은 모드에 의해 변형될 수 있다.
    • I 모드라면 원문을 소문자로 통일한 값과 비교한다.
  • 아래 형식으로 출력한다.
복호화 검증: OK

예외 처리

잘못된 입력이 들어오면 [ERROR]로 시작하는 메시지를 출력하고 해당 입력부터 다시 입력받는다.

예외 메시지

  • 원문 메시지가 규칙에 맞지 않는 경우
[ERROR] 원문 메시지 형식이 올바르지 않습니다.
  • 모드 입력이 규칙에 맞지 않는 경우
[ERROR] 모드 입력이 올바르지 않습니다.
  • 숫자 처리 모드 입력이 규칙에 맞지 않는 경우
[ERROR] 숫자 처리 모드 입력이 올바르지 않습니다.
  • 키 미리보기 출력 개수가 규칙에 맞지 않는 경우
[ERROR] 키 미리보기 출력 개수가 올바르지 않습니다.

실행 결과 예시 1 (E + K)

원문 메시지를 입력해 주세요.
Hello, World!
알파벳 처리 모드를 입력해 주세요. (E:대소문자 구분, I:대소문자 미구분)
E
숫자 처리 모드를 입력해 주세요. (K:유지, S:치환)
K
키 미리보기 출력 개수를 입력해 주세요. (5~20)
8

암호화를 시작합니다.
암호문: Jxdda, Qavds!
체크섬: 1079

키 미리보기
[대문자]
- A -> Q
- B -> T
- C -> A
- D -> Z
- E -> V
- F -> W
- G -> R
- H -> J
[소문자]
- a -> q
- b -> t
- c -> a
- d -> z
- e -> x
- f -> w
- g -> r
- h -> j

빈도 리포트 (TOP 3)
1) d : 3
2) a : 2
3) J : 1

복호화 검증: OK

위 암호문/키는 예시이며, 실제 실행 결과는 랜덤에 따라 달라질 수 있다.


실행 결과 예시 2 (I + S, 입력 오류 포함)

원문 메시지를 입력해 주세요.
Hello@World
[ERROR] 원문 메시지 형식이 올바르지 않습니다.
원문 메시지를 입력해 주세요.
Hello 2026!
알파벳 처리 모드를 입력해 주세요. (E:대소문자 구분, I:대소문자 미구분)
X
[ERROR] 모드 입력이 올바르지 않습니다.
알파벳 처리 모드를 입력해 주세요. (E:대소문자 구분, I:대소문자 미구분)
I
숫자 처리 모드를 입력해 주세요. (K:유지, S:치환)
Z
[ERROR] 숫자 처리 모드 입력이 올바르지 않습니다.
숫자 처리 모드를 입력해 주세요. (K:유지, S:치환)
S
키 미리보기 출력 개수를 입력해 주세요. (5~20)
3
[ERROR] 키 미리보기 출력 개수가 올바르지 않습니다.
키 미리보기 출력 개수를 입력해 주세요. (5~20)
20

암호화를 시작합니다.
암호문: jxddp 7879!
체크섬: 794

키 미리보기
[소문자]
- a -> q
- b -> t
- c -> a
- d -> z
- e -> x
- f -> w
- g -> r
- h -> j
- i -> v
- j -> n
- k -> b
- l -> d
- m -> o
- n -> c
- o -> p
- p -> s
- q -> u
- r -> i
- s -> f
- t -> l
[숫자]
- 0 -> 8
- 1 -> 1
- 2 -> 7
- 3 -> 2
- 4 -> 0
- 5 -> 6
- 6 -> 9
- 7 -> 4
- 8 -> 5
- 9 -> 3

빈도 리포트 (TOP 3)
1) 7 : 2
2) d : 2
3) 8 : 1

복호화 검증: OK


프로그래밍 요구 사항

  • JDK 21에서 실행 가능해야 한다.
  • 프로그램 실행의 시작점은 Applicationmain()이다.
  • System.exit()를 호출하지 않는다.
  • 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시키고,
    [ERROR]로 시작하는 메시지를 출력한 후 해당 입력부터 다시 받는다.

사용 가능한 라이브러리

  • camp.nextstep.edu.missionutils.RandomspickNumberInRange()를 사용한다.

예시

int index = Randoms.pickNumberInRange(0, candidates.size() - 1);

제출 안내

  • 과제 제출은 GitHub Repository에 push한 뒤 제출한다.
  • 기능 구현 후 ./gradlew clean test 실행 결과가 BUILD SUCCESSFUL인지 확인한다.

About

우테코 8기 3주차 문제인 "로또"에 기반한 자체 제작 문제입니다.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages