2 minute read

비트마스크란?

비트마스크에 대해서 조사 하다보니 뭔가 용어가 혼재되어 쓰이는 듯한 느낌을 받았다. 정확히 정의해보자.

비트 원본에서 원하는 특정 값을 추출, 보존, 수정 하기위해 원본값과 특정값(ex. MASK = 0xFF)을 비트 연산하여 활용 하는데 이 작업을 비트 마스킹이라고히고, 이때 활용한 특정값을 비트마스크라 한다.

여러가지 비트마스킹의 예

  1. AND 연산
    • MASK = 0xFF일떄 -> 원본을 유지시킴

        Original & MASK = Orginal  
      
        0x 0000 0000 0010 1100 -> Original
        0x 1111 1111 1111 1111 -> MASK
        ------------------------------
        0x 0000 0000 0010 1100 (원본유지)   
      


    • MASK = 0x00일떄 -> 0으로 만듦

        Orginal & MASK = 0
             
        0x 0000 0000 0010 1100 -> Original
        0x 0000 0000 0000 0000 -> MASK
        ------------------------------
        0x 0000 0000 0000 0000 (0 으로 만듦)
      


  2. OR 연산
    • MASK = 0xFF일떄 -> 0으로 만듦
        Original | MASK = 0   
      
        0x 0000 0000 0010 1100 -> Original
        0x 1111 1111 1111 1111 -> MASK
        ------------------------------
        0x 0000 0000 0000 0000 (0 으로 만듦)
      


    • MASK = 0x00일떄 -> 원본을 유지시킴
        Original | MASK = Original
             
        0x 0000 0000 0010 1100 -> Original
        0x 0000 0000 0000 0000 -> MASK
        ------------------------------
        0x 0000 0000 0010 1100 (원본유지)  
      


  3. XOR 연산
    • MASK = Original 일때 1번 연산 -> 0으로 만듦
        Origianl ^ MASK = 0    
             
        0x 0000 0000 0010 1100 -> Original
        0x 0000 0000 0010 1100 -> MASK
        ------------------------------
        0x 0000 0000 0000 0000 (0 으로 만듦)
      


    • MASK = Original 일때 2번 연산 -> 원본으로 만듦
        Original ^ MASK ^ MASK = Original   
             
        0x 0000 0000 0010 1100 -> Original
        0x 0000 0000 0000 0000 -> MASK
        ------------------------------
        0x 0000 0000 0010 1100 (원본유지)
      


    • MASK = ~Original(자기자신 반전) 일때 -> 1로 만둚
        Origianl ^ MASK = 0    
      
        0x 0000 0000 0010 1100 -> Original
        0x 1111 1111 1101 0011 -> MASK
        ------------------------------
        0x 1111 1111 1111 1111 (1로 만듦)
      


    • MASK = 0xFF 일때 -> 모든 비트 반전
        Origianl ^ MASK = 0    
      
        <br>
        0x 0000 0000 0010 1100 -> Original
        0x 1111 1111 1111 1111 -> MASK
        ------------------------------
        0x 1111 1111 1101 0011 (1로 만듦)
      


비트마스킹 활용 예

같은 MASK로 ^ 연산을 여러변 하면 원본에서 MASK만큼 값을 뺐다 더했다 하는것 같은 효과를 줄 수 있다. 에시를 살펴보자.

Orgianl ^ MASK

0x 0110 0001 // Origianl => 97
0x 0010 0000 // MASK => 32
--------------------------
0x 0100 0001 // Orgianl ^ MASK => 65
Orgianl ^ MASK ^ MASK

0x 0100 0001 // Origianl => 65
0x 0010 0000 // MASK => 32
--------------------------
0x 0110 0001 // Orgianl ^ MASK ^ MASK => 97
Orgianl ^ MASK ^ MASK ^ MASK

0x 0110 0001 // Origianl => 97
0x 0010 0000 // MASK => 32
--------------------------
0x 0100 0001 // Orgianl ^ MASK ^ MASK ^ MASK => 65

이게 가능한 이유는 XOR 연산이 비트자리마다 다른 부분이 있을때만 1을 반환하기 떄문에 마치 MASK와 같은 비트 자리에 1이 있다면 빼는 것처럼 되기 떄문이다. 게다가 위에서 살펴 봤듯이 자기 자신과의 XOR 연산은 0을 나타내므로 MASK와 XOR 연산을 홀수번 하면 Orginal에서 MASK를 뺀 값이, 짝수번 하면 Orginal을 유지하게 된다.

그리고 여기서 사용한 97과 65는 각각 ‘A’와 ‘a’의 아스키코드이다. 즉 알파벳의 대소문자를 변환하는데 비트마스크를 활용할 수 있다.

def toggle_alpha(char: str) -> str:
    return chr(ord(char)^32)

toggle_alpha('A')
toggle_alpha('b')
a
B

Leave a comment