컴퓨터상의 모든 문자들은 유일한 코드값에 대응되는데, 보통 ASCII 표준이 널리 쓰입니다. 예를 들면 대문자 A는 65, 별표(*)는 42, 소문자 k는 107라는 값을 가집니다.
현대적인 암호화 기법 중에, 텍스트 파일의 내용을 ASCII 코드로 바꾸고 각 바이트를 비밀키의 값으로 XOR 시키는 것이 있습니다. 이 방법의 장점은 암호화와 복호화에 동일한 키를 사용할 수 있다는 것입니다. 예를 들어 65 XOR 42 = 107 이고, 107 XOR 42 = 65 가 됩니다.
암호문을 절대 깰 수 없도록 하려면, 암호화할 문장의 길이와 같은 무작위의 비밀키를 만들면 됩니다. 암호문과 비밀키는 따로따로 보관해둬야 하고, 그 반쪽짜리 정보 두 개를 함께 확보하지 않는 한 해독은 불가능합니다.
하지만 이 방법은 대부분의 경우 실용적이지 못하므로, 원문보다 짧은 비밀키를 사용하게 됩니다. 이런 경우 비밀키는 전체 메시지에 대해서 반복적으로 돌아가며 적용됩니다. 이 때 키의 길이는 보안상 충분할 정도로 길어야 하지만 또한 쉽게 기억할 수 있을 정도로 짧아야 한다는 미묘한 균형이 요구됩니다.
이번 문제를 위해서 준비된 암호화 키는 단 3개의 영어 소문자이고, cipher1.txt 파일에 암호화된 ASCII 코드값이 들어있습니다. 원래의 메시지는 평범한 영어 문장임을 힌트로 삼아서 암호문을 해독하고, 원문에 포함된 모든 ASCII 코드 값의 총합을 구하세요.
일반적인 문장에서의 알파벳의 빈도 수를 추측하여 문제를 해결한다… 라고 생각해서 알파벳 ‘e’가 가장 많이 나올 것이라 추측하면 오산.
일반적인 문장에서는 ‘띄어쓰기’가 가장 많이 나온다.
참고로 복호화하여 나오는 문장은 다음과 같다.
(The Gospel of John, chapter 1) 1 In the beginning the Word already existed. He was with God, and he was God. 2 He was in the beginning with God. 3 He created everything there is. Nothing exists that he didn’t make. 4 Life itself was in him, and this life gives light to everyone. 5 The light shines through
the darkness, and the darkness can never extinguish it. 6 God sent John the Baptist 7 to tell everyone about the light so that everyone might believe because of his testimony. 8 John himself was not the light; he was only a witness to the light. 9 The one who is the true light, who gives light to everyone,
was going to come into the world. 10 But although the world was made through him, the world didn’t recognize him when he came. 11 Even in his own land and among his own people, he was not accepted. 12 But to all who believed him and accepted him, he gave the right to become children of God. 13 They are rebo
rn! This is not a physical birth resulting from human passion or plan, this rebirth comes from God.14 So the Word became human and lived here on earth among us. He was full of unfailing love and faithfulness. And we have seen his glory, the glory of the only Son of the Father.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#!/usr/bin/env perl use 5.010; use strict; use warnings; #명령행 인자로 파일 이름 넘겨줄 것. my @a; my @p; my $r = 0; @a = split /,/, $_ while (<>); push @{$p[$_%3]}, $a[$_] for (0..$#a); for (0..2) { my @u = @{$p[$_]}; my $k = k(@{$p[$_]}); for (0..$#u) { $u[$_] = $k^$u[$_]; $r += $u[$_]; } @{$p[$_]} = @u; } say $r; sub k { my %h; for (@_) { $h{$_} = 1 if not defined $h{$_}; $h{$_}++ if defined $h{$_}; } my $t = 0; my $v; for (keys %h) { if ($h{$_} > $t) { $t = $h{$_}; $v = $_; } } return $v^ord(" "); } |