암호화-시저암호

Cryptography-Caesar

Posted by Hebi on December 5, 2022

암호화를 학습

암호학- 카이사르 암호 (시저암호)

시저암호

  • 카이사르 암호(혹은 시저 암호)는 가장 단순한 대치(substitution) 암호 중 하나로, 알파벳을 일정한 거리만큼 밀어서 평문을 암호화한다.
  • 이 암호의 이름은 로마의 카이사르가 쓰던 암호 방식에서 유래하였다.

  • 예를 들어, ‘ABC’라는 문자열을 3만큼 밀면 ‘DEF’가 된다. 이렇게 밀기 전의 문자와 밀고 난 후의 문자는 알파벳 순서가 유지되어야 한다. 따라서 ‘Z’를 1만큼 밀면 ‘A’가 되어야 한다.

  • 카이사르 암호는 고대 로마 시대에 널리 사용되었으며, 그 당시에는 비교적 안전하다고 여겨졌다 .
  • 하지만 현대적인 컴퓨터를 이용한 무차별 대입 공격(brute-force attack)에서는 비교적 쉽게 해독될 수 있기 때문에, 보안적으로 안전한 암호 방식이 아니다.

  • 그러나 카이사르 암호는 암호학의 기본적인 개념을 이해하는 데에 유용하며, 이를 변형한 다양한 암호 방식이 개발되었다.
  • 예를 들어, 카이사르 암호의 shift 값인 3을 매번 변경하는 것으로 간단하게 암호화의 강도를 높일 수 있다.
  • 이렇게 간단한 기법을 응용하여 다양한 암호화 기법이 개발되었으며, 이를 기반으로 보다 강력한 암호화 방식이 개발되었다.
평문 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
암호문 D E F G H I J K L M N O P Q R S T U V W X Y Z A B C

카이사르2

Code

1
2
3
4
5
pub fn encryption(
    string: &str,//암호화할 문자열
    shifts: u8,//시저암호에서 사용할 이동거리
    lang_arr: Vec<char>,//사용할 문자집합
    lang_arr_upper: Vec<char>,//대문자로 변경할 문자 집합
  • string: 암호화할 문자열이다.
  • shifts: 시저 암호에서 사용할 이동 거리이다.
  • lang_arr: 사용할 문자 집합이다.
  • lang_arr_upper: 문자 집합 lang_arr의 순서를 유지하는 데 사용되는 문자 배열이다.
1
 Result<String, Box<dyn std::error::Error>>
  • 함수는 Result<String, Box<dyn std::error::Error»를 반환한다. 반환된 값이 Ok인 경우 암호화된 문자열이 포함되며, Err인 경우는 std::error::Error의 하위 유형의 오류가 포함된다.
1
 let letters: HashMap<usize, &char> = lang_arr_upper.iter().enumerate().collect();
  1. letters 변수에 lang_arr2를 열거하면서 각 문자의 인덱스를 저장하는 HashMap을 만든다.
1
2
3
4
5
 let numbers: HashMap<char, usize> = lang_arr
        .iter()
        .enumerate()
        .map(|(idx, chr)| (chr.clone(), idx))
        .collect();
  1. numbers 변수에 lang_arr를 열거하면서 각 문자와 인덱스를 저장하는 HashMap을 만든다.
1
2
3
  Ok(string
        .chars()
        .map(|c| {
  1. string을 chars() 메서드를 사용하여 char 타입의 반복자로 변환한다.
    • map() 메서드를 사용하여 문자열의 각 문자에 대해 시저 암호를 수행한다.
1
2
   if c == ' ' {//    * 문자가 공백인 경우 그대로 반환합니다.
                c
    • 문자가 공백인 경우 그대로 반환한다.
1
2
3
4
5
6
 let shift = numbers[&c] + shifts as usize;

                //* 이동 후 인덱스가 lang_arr의 범위를 벗어나는 경우, letters HashMap을 사용하여 알파벳을 순환
                if shift > lang_arr.len() - 1 {
                    //letter shift % 배열의 크기만큼으로 변경
                    *letters[&(shift % lang_arr.len())]
    • 문자가 알파벳인 경우, numbers HashMap을 사용하여 문자의 인덱스를 얻고 shifts 만큼 이동한다.
1
  if shift > lang_arr.len() - 1 {
    • 이동 후 인덱스가 lang_arr의 범위를 벗어나는 경우, letters HashMap을 사용하여 알파벳을 순환시킨다.
1
2
3
4
 else {
                    //순환시키지 않아도 되는 경우, letters HashMap을 사용하여 인덱스를 문자로 변환합니다
                    *letters[&shift]
                }
    • 순환시키지 않아도 되는 경우, letters HashMap을 사용하여 인덱스를 문자로 변환한다.
1
  .collect::<String>())
  1. collect() 메서드를 사용하여 암호화된 문자열을 생성합니다.

전체코드