본문 바로가기

Algorithm/암호화 알고리즘

[암호학] 단일치환 암호_시저암호

- 치환 암호(Substitution Cipher)

  : 평문의 문자를 다른 문자로 치환하는 암호

    

- 단일 치환 암호

 : 하나의 문자가 항상 다른 하나의 문자로 매핑

   랜덤한 매핑 테이블을 사용하여 치환하는 방식, 일정한 수(Key)를 더해서 암호를 생성하는 덧셈 암호, 일정한 수를 곱해     서 암호를 생성하는 곱셈 암호, 덧셈과 곱셈을 모두 사용하는 암호 등이 있다. 

 

- 시저 암호 

  : 문자를 일정한 간격만큼 이동하여 암호를 생성하는 방식.

 ex ) A는 3만큼 이동하여 D로 만들고, B를 3만큼 이동하여 E로 만드는 것과 같은 방식

 송수신자는 문자를 N만큼 Shift 한다는 것(Shift Key)을 알고 있는 상태에서 메시지를 암,복호화

 

public class CaesarCipher
    {
        private const int DEFAULT_KEY = 3;
        private readonly int key;

        public CaesarCipher(int key = DEFAULT_KEY)
        {
            this.key = key;
        }

        public string Encrypt(string message)
        {
            char[] a = message.ToCharArray();

            for (int i = 0; i < a.Length; i++) {
                //문자가 공백인지여부를 판단
                if (char.IsWhiteSpace(a[i])) continue;
                // 영문자를 Key 만큼 이동한 값이 알파벳의 마지막 문자보다 클 경우,
                // 알파벳의 처음으로 돌아오도록 하기 위해
                a[i] = (char)('A' + (a[i] - 'A' + key) % 26);
            }

            return new string(a);
        }

        public string Decrypt(string cipher) {
            char[] a = cipher.ToCharArray();

            for (int i = 0; i < a.Length; i++) {
                if (char.IsWhiteSpace(a[i])) continue;

                int ch = (a[i] - 'A' + 26 - key) % 26;
                a[i] = (char)('A' + ch);
            }

            return new string(a);
        }

        //테스트
        internal static void HowToTest() {
            string message = "ATTACK WEST CASTLE".ToUpper();
            var caesar = new CaesarCipher();
            string cipher = caesar.Encrypt(message);
            string plain = caesar.Decrypt(cipher);

            Console.WriteLine($"{message},{cipher},{plain}");
            Debug.Assert(cipher == "DWWDFN ZHVW FDVWOH");
            Debug.Assert(message == plain);
           
        }
        
    }

- 메인 메소드

      static void Main(string[] args)
        {
            // 시저 암호
            CaesarCipher caesarCipher = new CaesarCipher();
            var encryptStr = caesarCipher.Encrypt("HELLO");
            var decryptStr = caesarCipher.Decrypt(encryptStr);

            Console.WriteLine("암호화:" + encryptStr);
            Console.WriteLine("복호화:" + decryptStr);
        }

- 결과