Q & A

비트 XOR 연산자는 어디에 사용하나요?

비트 XOR 연산자는 간단한 암호화에 사용됩니다.

int plane = 100;    // 평문
int key = 57;       // 암호키

int encrypted = plane ^ key;    // 암호화
printf("%d\n", encrypted);      // 93

int decrypted = encrypted ^ key;   // 복호화
printf("%d\n", decrypted);         // 100: 평문 plane과 같음

평문과 암호키를 비트 XOR 연산하면 암호화된 값이 나옵니다. 이 암호화된 값과 암호키를 비트 XOR 연산하면 암호화된 값이 복호화됩니다(평문이 됨). 즉, XOR은 다음과 같은 특성을 가집니다.

  • a ^ b = c
  • c ^ b = a
  • c ^ a = b

참고로 XOR 암호화는 너무 간단하게 풀리기 때문에 실무에서는 거의 사용하지 않으며 안전성이 검증된 암호화 알고리즘(AES, RSA 등)을 사용합니다.

XOR의 특성을 활용하면 임시 변수를 사용하지 않고 두 변수의 값을 바꿀 수도 있습니다. 먼저 임시 변수를 사용하여 두 변수의 값을 바꾸는 코드입니다.

int a = 10;
int b = 20;
int temp;    // 임시 변수

temp = a;
a = b;
b = temp;

// a와 b의 값이 서로 바뀜
printf("%d\n", a);    // 20
printf("%d\n", b);    // 10

이번에는 임시 변수 없이 비트 XOR 연산자를 세 번 사용해서 두 변수의 값을 바꿉니다.

int a = 10;
int b = 20;

a = a ^ b;
b = a ^ b;
a = a ^ b;

// a와 b의 값이 서로 바뀜
printf("%d\n", a);    // 20
printf("%d\n", b);    // 10

나누기 2를 하는 좋은 방법은 무엇인가요?

2의 거듭제곱을 할 때 시프트 연산을 사용했습니다. 그렇다면 2를 나눌 때도 시프트 연산이 좋을까요?

a = a >> 1;   // 시프트 연산

b = b / 2;    // 나누기 연산

사실 이 두 연산은 서로 다릅니다. 예를 들어 음수에 시프트 연산과 나누기 연산을 해보면 결과가 다르게 나옵니다.

-5 >> 1 = -3
-5 / 2 = -2

숫자를 비트로 다룰 때는 비트 연산자를 사용하고, 그냥 숫자를 다룰 때는 나누기 연산자를 사용해야 합니다.