int
をbyte[]
に変換する必要があります。それを行う1つの方法は、BitConverter.GetBytes()
を使用することです。ただし、それが次の仕様に一致するかどうかは不明です。
XDR符号付き整数は、範囲[-2147483648,2147483647]の整数をエンコードする32ビットのデータです。整数は2の補数表記で表されます。最上位バイトと最下位バイトはそれぞれ0と3です。整数は次のように宣言されます。
ソース:RFC1014 3.2
上記の仕様を満たすintからバイトへの変換を行うにはどうすればよいですか?
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)
は、エンディアンネスが間違っていることを除いて、ほとんどあなたが望むことをします。
IPAddress.HostToNetwork メソッドを使用して、BitConverter.GetBytes
を使用する前に整数値内のバイトをスワップするか、Jon Skeetの EndianBitConverterクラス を使用できます。両方のメソッドは、移植性に関して正しいことを行います。
int value;
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value));
Two's Complementを含む数を表すさまざまな方法に関するより一般的な情報が必要な場合は、以下を参照してください。
Two's Complement および Signed Number Representation ウィキペディア
上記のサンプルのすべてのコードがなぜ...
明示的なレイアウトを持つ構造体は両方の方法で機能し、パフォーマンスに影響はありません。
更新:エンディアンに対処する方法についての質問があるので、それを抽象化する方法を示すインターフェイスを追加しました。別の実装構造体は反対のケースに対処できます
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 => b0;
public byte B2 => b0;
public byte B3 => b0;
}