[go] 바이너리 데이터에서 비트 단위로 작업하는 방법

바이너리 데이터는 0과 1로 구성된 이진 형식의 데이터를 나타냅니다. 바이너리 데이터에서 비트 단위로 작업하는 것은 비트 조작(bit manipulation)이라고 합니다. 이 글에서는 Go 언어를 사용하여 바이너리 데이터에서 비트 단위로 작업하는 방법에 대해 다루겠습니다.

1. 비트 단위 논리 연산

Go 언어는 & (AND), | (OR), ^ (XOR), &^ (AND NOT)와 같은 비트 단위 논리 연산자를 제공합니다. 이러한 연산자를 사용하여 바이너리 데이터의 비트를 조작할 수 있습니다.

예를 들어, 다음은 두 개의 바이너리 데이터에 대해 AND 연산을 수행하는 예제 코드입니다:

package main

import "fmt"

func main() {
    var a uint = 60    // 60의 2진수 표현은 00111100
    var b uint = 13    // 13의 2진수 표현은 00001101
    var result uint

    result = a & b   // 비트 단위 AND 연산

    fmt.Printf("결과: %d\n", result)    // 출력: 12 (12의 2진수 표현은 00001100)
}

2. 비트 단위 시프트 연산

비트 단위 시프트 연산은 << (왼쪽 시프트)와 >> (오른쪽 시프트) 연산자를 사용하여 바이너리 데이터의 비트를 왼쪽이나 오른쪽으로 이동시킵니다.

다음은 바이너리 데이터를 왼쪽으로 2비트 시프트하는 예제 코드입니다:

package main

import "fmt"

func main() {
    var a uint = 8    // 8의 2진수 표현은 00001000
    var result uint

    result = a << 2   // 비트 단위 왼쪽 시프트 연산

    fmt.Printf("결과: %d\n", result)    // 출력: 32 (32의 2진수 표현은 00100000)
}

3. 바이너리 데이터 다루기

Go 언어에서는 encoding/binary 패키지를 사용하여 바이너리 데이터를 읽고 쓸 수 있습니다. 이 패키지를 활용하여 특정 비트 위치에서 값을 읽거나 쓸 수 있습니다.

package main

import (
	"encoding/binary"
	"fmt"
	"bytes"
)

func main() {
	buf := new(bytes.Buffer)
	val := uint16(512)  // 2진수로는 0000001000000000

	err := binary.Write(buf, binary.LittleEndian, val)
	if err != nil {
		fmt.Println("binary.Write failed:", err)
	}

	bytes := buf.Bytes()

	// 바이너리 데이터의 1번째 비트 읽기
	bit := (bytes[0] >> 1) & 1
	fmt.Printf("1번째 비트: %d\n", bit)    // 출력: 0
}

위 예제에서는 encoding/binary 패키지를 사용하여 바이너리 데이터를 읽고 있습니다.

바이너리 데이터에서 비트 단위로 작업하기 위한 세 가지 방법을 살펴보았습니다. 이러한 작업은 종종 네트워크 프로그래밍이나 저수준 시스템 프로그래밍에서 유용하게 활용됩니다.

관련 참고 자료: