development

정수에서 바이트 배열로

big-blog 2021. 1. 10. 19:49
반응형

정수에서 바이트 배열로


.net에는 int를 바이트 배열로 변환하는 데 사용할 수있는 쉬운 변환 방법이 있다고 생각했습니다. 나는 빠른 검색을했고 모든 솔루션은 "좋은 ol 시절"과 같이 한 번에 한 바이트 씩 비트 마스킹 / 시프트입니다. 어딘가에 ToByteArray () 메서드가 없습니까?


byte[] bytes = BitConverter.GetBytes(i);

당신이 것 또한주의 비록 확인하려면 BitConverter.IsLittleEndian나타날 것입니다 그 어떤 방법으로 주위를 볼 수 있습니다!

이 작업을 반복적으로 수행하는 경우 시프트 연산 ( >>/ <<)을 통해 직접 작성 하거나 unsafe코드 를 사용하여 모든 단기 배열 할당을 피할 수 있습니다 . 시프트 작업 플랫폼의 엔디안에 영향을받지 않는다는 장점 있습니다. 당신은 항상 당신이 그들을 기대하는 순서로 바이트를 얻을.


Marc의 대답은 물론 정답입니다. 그러나 그가 대안으로 시프트 연산자와 안전하지 않은 코드를 언급했기 때문에. 덜 일반적인 대안을 공유하고 싶습니다. Explicit레이아웃이 있는 구조체 사용 . 이것은 원칙적으로 C / C ++와 유사 union합니다.

다음은 Int32 데이터 유형의 구성 요소 바이트를 가져 오는 데 사용할 수있는 구조체의 예입니다. 좋은 점은 두 가지 방법으로 바이트 값을 조작하고 Int에 미치는 영향을 볼 수 있다는 것입니다.

  using System.Runtime.InteropServices;

  [StructLayout(LayoutKind.Explicit)]
  struct Int32Converter
  {
    [FieldOffset(0)] public int Value;
    [FieldOffset(0)] public byte Byte1;
    [FieldOffset(1)] public byte Byte2;
    [FieldOffset(2)] public byte Byte3;
    [FieldOffset(3)] public byte Byte4;

    public Int32Converter(int value)
    {
      Byte1 = Byte2 = Byte3 = Byte4 = 0;
      Value = value;
    }

    public static implicit operator Int32(Int32Converter value)
    {
      return value.Value;
    }

    public static implicit operator Int32Converter(int value)
    {
      return new Int32Converter(value);
    }
  }

위는 이제 다음과 같이 사용할 수 있습니다.

 Int32Converter i32 = 256;
 Console.WriteLine(i32.Byte1);
 Console.WriteLine(i32.Byte2);
 Console.WriteLine(i32.Byte3);
 Console.WriteLine(i32.Byte4);

 i32.Byte2 = 2;
 Console.WriteLine(i32.Value);

물론 불변성 경찰은 마지막 가능성에 대해 흥분하지 않을 수 있습니다. :)


이것은 OT 일 수 있지만 많은 기본 유형 또는 POD 구조를 직렬화하는 경우 .Net 용 Google 프로토콜 버퍼 가 유용 할 수 있습니다. 이것은 다른 유용한 기능 중에서 @Marc가 위에서 제기 한 엔디안 문제를 해결합니다.


Google에서 여기로 온 경우

이전 질문에 대한 대체 답변은 인덱스 오프셋을 사용하여 기본 데이터 유형을 byte []에 직접 쓸 수있는 도구가있는 John Skeet의 라이브러리를 참조합니다. BitConverter성능이 필요한 경우 보다 훨씬 좋습니다 .

Older thread discussing this issue here

John Skeet's Libraries are here

Just download the source and look at the MiscUtil.Conversion namespace. EndianBitConverter.cs handles everything for you.


Most of the answers here are either 'UnSafe" or not LittleEndian safe. BitConverter is not LittleEndian safe. So building on an example in here (see the post by PZahra) I made a LittleEndian safe version simply by reading the byte array in reverse when BitConverter.IsLittleEndian == true

void Main(){    
    Console.WriteLine(BitConverter.IsLittleEndian); 
    byte[] bytes = BitConverter.GetBytes(0xdcbaabcdfffe1608);
    //Console.WriteLine(bytes); 
    string hexStr = ByteArrayToHex(bytes);
    Console.WriteLine(hexStr);
}

public static string ByteArrayToHex(byte[] data) 
{ 
   char[] c = new char[data.Length * 2]; 
   byte b; 
  if(BitConverter.IsLittleEndian)
  {
        //read the byte array in reverse
        for (int y = data.Length -1, x = 0; y >= 0; --y, ++x) 
        { 
            b = ((byte)(data[y] >> 4)); 
            c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
            b = ((byte)(data[y] & 0xF)); 
            c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
        }               
    }
    else
    {
        for (int y = 0, x = 0; y < data.Length; ++y, ++x) 
        { 
            b = ((byte)(data[y] >> 4)); 
            c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
            b = ((byte)(data[y] & 0xF)); 
            c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
        }
    }
    return String.Concat("0x",new string(c));
}

It returns this:

True
0xDCBAABCDFFFE1608

which is the exact hex that went into the byte array.

ReferenceURL : https://stackoverflow.com/questions/4176653/int-to-byte-array

반응형