C#/Advanced C#

[C#] BitConverter 클래스

로파이 2022. 4. 14. 23:48

System.BitConverter 클래스를 통해서 리터럴 타입의 변수 (int, long 등)의 값을 byte[] 바이트로 변환한 값을 얻을 수 있다. 

 

리틀 엔디안 시스템

MSB(Most Significant Bit)가 낮은 주소에 할당 된다. LSB(Least Significant Bit)가 높은 주소로 온다.

정확히는 바이트 단위로 할당된다. ex) 0x09ABCDEF -> (낮은 주소) | EF | CD | AB | 09 | (높은 주소)식으로 만들어진다.

Console.WriteLine(BitConverter.IsLittleEndian); // 리틀 엔디안 시스템

 

바이트 데이터 출력

바이트 배열을 출력하는 헬퍼 함수

public static void PrintBytes(byte[] bytes)
{
    var bytesInStr = String.Join("", bytes.Select(b => String.Format("{0:X02}", b)));
    var bytesInStrHex = $"0x{bytesInStr}";
    Console.WriteLine(bytesInStrHex);
}

 

4바이트와 8바이트 값의 변환

리틀 엔디안 시스템을 따라 변환된 바이트 배열을 얻을 수 있다.

var value1 = 0x09ABCDEF;
var bytes1 = BitConverter.GetBytes(value1);
PrintBytes(bytes1); // 0xEFCDAB09

var value2 = 0x0506070809ABCDEF;
var bytes2 = BitConverter.GetBytes(value2);
PrintBytes(bytes2); // 0XEFCDAB0908070605

 

C#에서 char 타입은 2바이트이다.

var value3 = 'a'; // 97 (0x61) C#에서 char타입은 2바이트를 사용한다.
var bytes3 = BitConverter.GetBytes(value3);
PrintBytes(bytes3); // 0x6100


String의 경우 Encoding의 변환 클래스 ASCII, UTF8 등의 엔코딩 방식에 따라 선택하여 byte[]로 변환한다.

var value4 = "안녕 세상"; // String의 경우 Encoding을 사용해야한다.  
var bytes4 = Encoding.UTF8.GetBytes(value4);
PrintBytes(bytes4);
Console.WriteLine(Encoding.UTF8.GetString(bytes4));


DateTime의 경우 long 값으로 변환하여 사용한다. Ticks라는 속성은 DateTime.MinValue(0001-01-01 오전 12:00:00)을 기준으로 지난 값이다.

DateTime value5 = DateTime.Now;
Console.WriteLine(value5);
var bytes5 = BitConverter.GetBytes(value5.ToBinary()); // DateTime의 Tick 속성을 이용
PrintBytes(bytes5);
Console.WriteLine(DateTime.FromBinary(BitConverter.ToInt64(bytes5)));


bool 타입은 1바이트를 사용한다.

var value6 = true;
var bytes6 = BitConverter.GetBytes(value6);
PrintBytes(bytes6); // 0x01

 

byte[] 데이터를 역으로 리터럴 타입의 값으로 변환가능하며 TryWriteBytes 계열의 함수를 이용하여 메모리에 값을 byte[]로 변환하여 자동으로 쓰는 예외를 던지지 않는 함수를 사용가능하다.