[C#] C # int to 바이트 []

int를 사용하는 byte[]한 가지 방법 으로 변환해야 합니다 BitConverter.GetBytes(). 그러나 그것이 다음 사양과 일치하는지 확실하지 않습니다.

XDR 부호있는 정수는 [-2147483648,2147483647] 범위의 정수를 인코딩하는 32 비트 데이텀입니다. 정수는 2의 보수 표기법으로 표시됩니다. 최상위 바이트와 최하위 바이트는 각각 0과 3입니다. 정수는 다음과 같이 선언됩니다.

출처: RFC1014 3.2

위의 사양을 충족시키는 int to byte 변환을 어떻게 수행 할 수 있습니까?



답변

RFC는 부호있는 정수가 빅 엔디안 방식으로 바이트가 정렬 된 일반적인 4 바이트 정수라고 말하려고합니다.

이제, 당신은 아마도 리틀 엔디안 머신에서 작업하고 있고 반대로 BitConverter.GetBytes()당신에게 줄 byte[]것이다. 그래서 당신은 시도 할 수 있습니다 :

int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
Array.Reverse(intBytes);
byte[] result = intBytes;

그러나 코드를 가장 이식하기 쉽게하려면 다음과 같이하면됩니다.

int intValue;
byte[] intBytes = BitConverter.GetBytes(intValue);
if (BitConverter.IsLittleEndian)
    Array.Reverse(intBytes);
byte[] result = intBytes;


답변

여기에는 또 다른 방법이 있습니다. 모두 1x 바이트 = 8x 비트를 알고 있고 “정규”정수 (int32)에는 32 비트 (4 바이트)가 들어 있습니다. >> 연산자를 사용하여 비트를 오른쪽으로 이동할 수 있습니다 (>> 연산자는 값을 변경하지 않습니다).

int intValue = 566;

byte[] bytes = new byte[4];

bytes[0] = (byte)(intValue >> 24);
bytes[1] = (byte)(intValue >> 16);
bytes[2] = (byte)(intValue >> 8);
bytes[3] = (byte)intValue;

Console.WriteLine("{0} breaks down to : {1} {2} {3} {4}",
    intValue, bytes[0], bytes[1], bytes[2], bytes[3]);


답변

BitConverter.GetBytes(int) 엔디안이 잘못되었다는 것을 제외하고는 원하는 것을 거의 수행합니다.

Jon Skeet의 EndianBitConverter 클래스 를 사용 하거나 사용 하기 전에 IPAddress.HostToNetwork 메소드를 사용하여 정수 값 내의 바이트를 교환 할 수 있습니다 . 두 가지 방법 모두 이식성과 관련하여 올바른 일을합니다.BitConverter.GetBytes

int value;
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value));


답변

이 설명을 볼 때이 xdr 정수는 단지 빅 엔디안 “표준”정수이지만 가장 난독 한 방식으로 표현된다는 느낌이 듭니다. 2의 보수 표기법 은 U2로 더 잘 알려져 있으며 오늘날의 프로세서에서 사용하고 있습니다. 바이트 순서는 빅 엔디안 표기법 임을 나타냅니다 .
따라서 질문에 대답하면 리틀 엔디안으로 인코딩되므로 배열 (0 <-> 3, 1 <-> 2)의 요소를 역으로 사용해야합니다. 확인 BitConverter.IsLittleEndian하려면 먼저 어떤 컴퓨터에서 실행 중인지 확인해야합니다 .


답변

위의 샘플 에서이 코드가 모두 왜 …

명시적인 레이아웃을 가진 구조체는 두 가지 방식으로 작동하며 성능 저하가 없습니다.

업데이트 : 엔디안 처리 방법에 대한 질문이 있으므로 추상화 방법을 설명하는 인터페이스를 추가했습니다. 다른 구현 구조체는 반대의 경우를 다룰 수 있습니다

public interface IIntToByte
{
    Int32 Int { get; set;}

    byte B0 { get; }
    byte B1 { get; }
    byte B2 { get; }
    byte B3 { get; }
}

[StructLayout(LayoutKind.Explicit)]
public struct IntToByteLE : UserQuery.IIntToByte
{
    [FieldOffset(0)]
    public Int32 IntVal;

    [FieldOffset(0)]
    public byte b0;
    [FieldOffset(1)]
    public byte b1;
    [FieldOffset(2)]
    public byte b2;
    [FieldOffset(3)]
    public byte b3;

    public Int32 Int {
        get{ return IntVal; }
        set{ IntVal = value;}
    }

    public byte B0 => b0;
    public byte B1 => b1;
    public byte B2 => b2;
    public byte B3 => b3;
}


답변

2의 보수를 포함하여 숫자를 나타내는 다양한 방법에 대한보다 일반적인 정보를 원하면 다음을 살펴보십시오.

Wikipedia에서 2의 보완서명 된 숫자 표현


답변

다른 방법은 BinaryPrimitives 를 사용하는 것입니다.

byte[] intBytes = BitConverter.GetBytes(123);
int actual = BinaryPrimitives.ReadInt32LittleEndian(intBytes);