質問
.NETには、INTをバイト配列に変換するために使用する簡単な変換方法があると思いましたか?私は簡単な検索を行いましたが、すべてのソリューションは、「The Good ol Days」のように、一度に1バイトをマスキング/シフトしています。どこかにtobytearray()メソッドはありませんか?
解決
byte[] bytes = BitConverter.GetBytes(i);
あなたも注意してください そうかもしれない チェックしたい BitConverter.IsLittleEndian
それがどのように現れるかを見るために!
あなたがこれをしている場合に注意してください 繰り返し どちらかのシフト操作を介して自分で書くことにより、これらの短命の配列割り当てをすべて避けたいかもしれません>>
/ <<
)、または使用して unsafe
コード。シフト操作 また 彼らがあなたのプラットフォームのエンディアン性の影響を受けないという利点があります。君 いつも 予想される順序でバイトを取得します。
他のヒント
マークの答えはもちろん正しい答えです。しかし、彼は代替としてシフト演算子と安全でないコードに言及して以来です。あまり一般的ではない代替品を共有したいと思います。で構造体を使用します Explicit
レイアウト。これは、c/c ++とのプリンシパルが似ています union
.
以下は、int32データ型のコンポーネントバイトに到達するために使用できる構造体の例です。良いことは、2つの方法で、バイト値を操作して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かもしれませんが、多くの原始的なタイプまたはポッド構造をシリアル化している場合、 .NET用のGoogleプロトコルバッファー あなたに役立つかもしれません。これは、他の有用な機能の中でも、上記の上記のEndianness Issue @Marcの問題に対処しています。
Googleからここに来たら
古い質問に対する代替回答とは、インデックスオフセットでプリミティブデータ型を直接バイトに書くことができるツールを備えたジョンスキートのライブラリを指します。はるかに優れています BitConverter
パフォーマンスが必要な場合。
ソースをダウンロードして、を見てください MiscUtil.Conversion
名前空間。 EndianBitConverter.cs
あなたのためにすべてを処理します。
ここでの答えのほとんどは「安全でない」かLittleendian Safeではありません。BitConverterはLittleendian Safeではありません。 ここ (Pzahraによる投稿を参照)BitConverter.islittleRendian == 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));
}
これを返します:
True
0xDCBAABCDFFFE1608
これは、バイト配列に入った正確な16進数です。