암호화를 학습
암호학- 카이사르 암호 (시저암호)
- 카이사르 암호(혹은 시저 암호)는 가장 단순한 대치(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 |
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();
- 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();
- numbers 변수에 lang_arr를 열거하면서 각 문자와 인덱스를 저장하는 HashMap을 만든다.
1
2
3
Ok(string
.chars()
.map(|c| {
- 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>())
- collect() 메서드를 사용하여 암호화된 문자열을 생성합니다.