C#十六进制转结构

C# hexadecimal to struct

我有不同种类的长度为 8 的十六进制数,例如 FFFFFFFA(4 字节 255、255、255 和 250 ASCII 编码)。将其转换为二进制给出:11111111 11111111 11111111 11111010 其中每个数字代表真 (1) 或假 (0)。

最好在 C# 中有某种对象,其中每个 属性 代表一个二进制文件。在本例中,对象具有 32 个布尔属性。

在 Internet 上搜索使我了解了结构,但我不知道该怎么做。

具体问题:如何将十六进制转换为结构并返回?

任何方向都可以!

提前致谢!

你可以试试System.Collections.BitArray

一些演示:

   using System.Collections;
   using System.Linq;

   ...

   int original = 123;

   // Create array from int
   BitArray array = new BitArray(new int[] {original});

   // Access to the single Bit (which is represented as bool)
   Console.WriteLine(array[0] ? "Y" : "N");

   // Let's have a look at all bits within the array
   Console.WriteLine(string.Concat(array.Cast<bool>().Select(x => x ? 1 : 0)));

   // Restore int from the array
   int back = array
     .Cast<bool>()
     .Reverse()
     .Aggregate(0, (s, a) => s * 2 + (a ? 1 : 0));

   Console.WriteLine(back);

结果:

Y
11011110000000000000000000000000
123

How can I convert hexadecimals to a struct and back?

我想这取决于您的十六进制数字的形式;你似乎有整数,所以你可以用一些方便的道具包装一个整数,这些道具只是屏蔽位关闭或打开:

struct Biteger{

    private int _x;

    public bool Bit0 {
      get => this[0];
      set => this[0] = value;
    }

    public bool Bit1 {
      get => this[1];
      set => this[1] = value;
    }

    //...

    public bool this[int index]{
      get => (_x & (1 << index)) != 0;
      set { _x = value ? _x | (1 << index) : _x & ~(1 << index); }
    }

    public static implicit operator int(Biteger b) => b._x;

    public static implicit operator Biteger(int i) => new Biteger{ _x = i };
}

您可以像这样使用它:

Biteger x = 0x81; //sets bits 7 and 0 for 0x81
    
x[6] = true; //sets bit 6 for adding 0x40

x.Bit5 = true; //sets bit 5 for adding 0x20
    
Console.WriteLine(((int)x).ToString("x")); //prints e1

如果您想将数据保存在位数组中,它可能看起来像

public struct Biteger{

    private BitArray _ba;

    public bool Bit0 {
      get => _ba[0];
      set { _ba[0] = value; }
    }

    ...

    public bool Bit31 {
      get => _ba[31];
      set { _ba[31] = value; }
    }

    public bool this[int index]{
      get => _ba[index];
      set { _ba[index] = value; }
    }

    public implicit operator int(Biteger b){
      int x = 0;
      for(int i = 0; i < 32; i++) if (b._ba[i]) x |= 1 << i;
      return x;
    }

    public static implicit operator Biteger(int i) => return new Biteger{ _ba = new(new[]{i}) };
}

感谢您的所有评论和样本。我最终使用了 BitVector32,因为它对布尔值和小整数更有效(更多信息的内存和性能开销:https://docs.microsoft.com/en-us/dotnet/api/system.collections.specialized.bitvector32?view=net-6.0

结构

// Size = 4 because BitVector32 is 4 bytes
[StructLayout(LayoutKind.Explicit, Size = 4, CharSet = CharSet.Ansi)]
public struct Foo
{
    public Foo() {
        // Creates and initializes a BitVector32.
        // 4 bytes
        // 00000000 00000000 00000000 00000000
        data = new BitVector32(0);

        bit1 = BitVector32.CreateMask();
        bit2 = BitVector32.CreateMask(bit1);
        bit3 = BitVector32.CreateMask(bit2);
        // ...
    }

    [FieldOffset(0)]
    public BitVector32 data;

    private static int bit1;

    private static int bit2;

    private static int bit3;

    public bool Bit1
    {
        get => data[bit1];
        set => data[bit1] = value;
    }

    public bool Bit2
    {
        get => data[bit2];
        set => data[bit2] = value;
    }

    public bool Bit3
    {
        get => data[bit3];
        set => data[bit3] = value;
    }

    public string ToHexString()
    {
        return data.Data.ToString("X");
    }
}

计划

// -- Hex to struct
// FFFFBBFF
// 255      255      187      255
// 11111111 11111111 10111011 11111111
// var bytes = "FFFFBBFF".ToBytes();
var bytes = { 255, 255, 187, 255 };

var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
var foo = (Foo)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Foo));
handle.Free();

Console.WriteLine(foo.Bit1);
Console.WriteLine(foo.Bit2);
Console.WriteLine(foo.Bit3);
// ...

// -- Or struct to hex
var foo = new Foo();
foo.Bit1 = true;
foo.Bit2 = false;
foo.Bit3 = true;
// ...

Console.WriteLine(foo.ToHexString());

我知道它并不完美,它对我有用,我希望它能帮助其他人。

祝你有愉快的一天!