본문 바로가기

Algorithm/암호화 알고리즘

[암호학] 단일치환 암호_랜덤 치환 암호

  •  랜덤 치환 암호(Random Substitution Cipher)

      - 각 문자마다 랜덤하게 다른 문자를 대응시킨 암호

      - 외부에서 랜덤 키를 제공받거나 자체적으로 랜덤 키 테이블을 생성해서 메시지를 암호화, 복호화한다.

      - 'A~Z 배열'로부터 랜덤하게 문자 하나를 선택해서 이를 순차적으로 매핑 테이블에 저장

          > 배열 삭제 후 다음 문자열을 매핑 테이블에 저장 > 모든 문자를 매핑 테이블에 저장할 때 까지 반복

 public class RandomCipher
    {
        // 랜덤 매핑 테이블
        private readonly char[] table;

        public RandomCipher(string keyTable = null) {
            // 외부에서 키를 제공할 경우 그 키를 사용
            if (keyTable != null) {
                Debug.Assert(keyTable.Length == 26);
                table = keyTable.ToCharArray();
            }
            else { //키가 제공되지 않을 경우 키 생성
                table = CreateRandomTable();                         
            }
        }

        // A ~ Z 중 하나씩 골라 랜덤 테이블에 저장
        private char[] CreateRandomTable()
        {
            List<char> randomTable = new List<char>();

            var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToList();
            Random random = new Random();

            while (alphabet.Count > 0) {
                int rand = random.Next(0, alphabet.Count - 1);
                randomTable.Add(alphabet[rand]);
                alphabet.RemoveAt(rand);
            }

            return randomTable.ToArray();

        }

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

            for (int i = 0; i < a.Length; i++) {
                a[i] = (a[i] == ' ') ? ' ' : table[a[i] - 'A'];
            }

            return new string(a);
        }

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

            for (int i = 0; i < a.Length; i++) {
                if (a[i] != ' ') {
                    for (int t = 0; t < table.Length; t++) {
                        if (a[i] == table[t]) {
                            a[i] = (char)('A' + t);
                            break;

                        } //end if
                    } //end for
                } //and if
            } //and for

            return new string(a);
        }
    }

- 메인메소드

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

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

            var encryptRot13Str = ROT13Cipher.Encrypt("HELLO");
            var decryptRot13Str = ROT13Cipher.Decrypt(encryptStr);

            RandomCipher randomCipher = new RandomCipher();
            Console.WriteLine("ROT13 암호화:" + encryptRot13Str);
            Console.WriteLine("ROT13 복호화:" + decryptRot13Str);

            var encryptRandomStr = randomCipher.Encrypt("HELLO");
            var decryptRandomStr = randomCipher.Decrypt(encryptStr);

            Console.WriteLine("Random 암호화:" + encryptRandomStr);
            Console.WriteLine("Random 복호화:" + decryptRandomStr);
        }

- 결과