質問

.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進数です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top