Как извлечь байты из типа UInt128

#c# #packetdotnet

#c# #packetdotnet

Вопрос:

Библиотека PacketDotNet определяет структуру UInt128 . См.:

Как преобразовать этот тип в простой байтовый массив в C #?

Комментарии:

1. Если вы просто включаете источник (вместо использования всей библиотеки), просто измените from private на public его поля только для чтения

2. Я автор PacketDotNet. Любые предложения по улучшению этого будут приветствоваться, не стесняйтесь открывать проблему в репозитории GitHub!

Ответ №1:

Он может быть приведен к BigTnteger вызову then ToByteArray() , как показано ниже.

 var number = new Uint128();

((BigInteger)number).ToByteArray();
 

Комментарии:

1. Обратите внимание на это ((BigInteger)UInt128.MaxValue).ToByteArray().Length == 17 . Для знака добавляется дополнительный байт.

Ответ №2:

Похоже, вы присваиваете его BigInteger переменной и используете ToByteArray() для этого метод.

 UInt128 n128 = 12345;
BigInteger bi = (BigInteger)n128;
byte[] ba = bi.ToByteArray();
 

Комментарии:

1. Обратите внимание на это ((BigInteger)UInt128.MaxValue).ToByteArray().Length == 17 . Для знака добавляется дополнительный байт.

Ответ №3:

Я также обнаружил для себя другую возможность:

 public static unsafe byte[] GetBytesFromUInt128(this UInt128 value)
{
    byte[] numArray = new byte[16];
    fixed (byte* numPtr = numArray)
        *(UInt128*) numPtr = value;
    return numArray;
}
 

Ответ №4:

Несколько забавных трюков, которые вы можете сделать с новым .net core:

 var ui = UInt128.MaxValue - 1;

{
    var span = MemoryMarshal.Cast<UInt128, byte>(MemoryMarshal.CreateReadOnlySpan(ref ui, 1));

    for (int i = 0; i < UInt128.SizeOf; i  )
    {
        Console.WriteLine(span[i]);
    }
}
 

и / или заданный

 [StructLayout(LayoutKind.Explicit)]
public struct UInt128Split
{
    [FieldOffset(0)]
    public UInt128 UInt128;

    [FieldOffset(0)]
    public ulong ULong1;

    [FieldOffset(1)]
    public ulong ULong2;

    [FieldOffset(0)]
    public uint UInt1;

    [FieldOffset(4)]
    public uint UInt2;

    [FieldOffset(8)]
    public uint UInt3;

    [FieldOffset(12)]
    public uint UInt4;

    [FieldOffset(0)]
    public byte Byte1;

    [FieldOffset(1)]
    public byte Byte2;

    [FieldOffset(2)]
    public byte Byte3;

    [FieldOffset(3)]
    public byte Byte4;

    [FieldOffset(4)]
    public byte Byte5;

    [FieldOffset(5)]
    public byte Byte6;

    [FieldOffset(6)]
    public byte Byte7;

    [FieldOffset(7)]
    public byte Byte8;

    [FieldOffset(8)]
    public byte Byte9;

    [FieldOffset(9)]
    public byte Byte10;

    [FieldOffset(10)]
    public byte Byte11;

    [FieldOffset(11)]
    public byte Byte12;

    [FieldOffset(12)]
    public byte Byte13;

    [FieldOffset(13)]
    public byte Byte14;

    [FieldOffset(14)]
    public byte Byte15;

    [FieldOffset(15)]
    public byte Byte16;
}
 

затем

 var ui = UInt128.MaxValue - 1;

{
    ref UInt128Split rf = ref Unsafe.As<UInt128, UInt128Split>(ref ui);

    Console.WriteLine(rf.UInt1);
    Console.WriteLine(rf.UInt2);
    Console.WriteLine(rf.UInt3);
    Console.WriteLine(rf.UInt4);

    Console.WriteLine(rf.ULong1);
    Console.WriteLine(rf.ULong2);

    // rf is the same as ui, so if we modify rf we modify ui!
    Console.WriteLine(ui);
    rf.ULong1 -= 11454;
    Console.WriteLine(ui);
}