C # получение информации из шестнадцатеричных данных - PullRequest
0 голосов
/ 07 марта 2011

У меня есть шестнадцатеричные данные:

byte[] data = new Byte[] {
    0xC1, 0x3A, 0x00, 0x01, 0x5D, 0xDA, 0x47, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0xF0, 0xFC, 0x12, 0x00, 0x00, 0x00
};

У меня есть структура C ++:

struct SERVICE
{
    unsigned char c;
    unsigned char size;
    unsigned char headcode;
    unsigned char Type;
    unsigned short Port;
    char ServiceName[50];
    unsigned short ServiceCode;
};

У меня вопрос: как получить из данных ServiceName, Port и т. Д.

Извините за мой плохой английский

Ответы [ 3 ]

1 голос
/ 07 марта 2011

Вот один из способов сделать это:

struct SERVICE
{
    public byte c;
    public byte size;
    public byte headcode;
    public byte Type;
    public ushort Port;
    public string ServiceName;
    public ushort ServiceCode;
};

string GetNullTerminatedString(byte[] data, Encoding encoding)
{
    int index = Array.IndexOf(data, (byte)0);
    if (index < 0)
    {
        Debug.WriteLine("No string terminator found.");
        index = data.Length;
    }

    return encoding.GetString(data, 0, index);
}

SERVICE ByteArrayToService(byte[] array, Encoding encoding)
{
    using (MemoryStream stream = new MemoryStream(array))
    {
        using (BinaryReader reader = new BinaryReader(stream))
        {
            SERVICE service = new SERVICE();
            service.c = reader.ReadByte();
            service.size = reader.ReadByte();
            service.headcode = reader.ReadByte();
            service.Type = reader.ReadByte();
            service.Port = reader.ReadUInt16();
            service.ServiceName = GetNullTerminatedString(reader.ReadBytes(50), encoding);
            service.ServiceCode = reader.ReadUInt16();
            return service;
        }
    }
}

void Main(string[] args)
{
    byte[] data = new Byte[]
    {
        0xC1, 0x3A, 0x00, 0x01, 0x5D, 0xDA, 0x47, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0xF0, 0xFC, 0x12, 0x00, 0x00, 0x00
    };

    SERVICE s = ByteArrayToService(data, Encoding.Default);
}

Предполагается, что двоичный массив использует тот же Endianess, что и ваша архитектура.Если это не так, вы можете использовать EndianBinaryReader из библиотеки MiscUtil .

Редактировать: это также хорошее решение, которое полностью избегает читателя.Однако нельзя напрямую указать кодировку, используемую для строки, и структура памяти структуры должна соответствовать структуре, используемой в байтовом массиве.

[StructLayout(LayoutKind.Sequential)]
struct SERVICE
{
    public byte c;
    public byte size;
    public byte headcode;
    public byte Type;
    public ushort Port;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
    public string ServiceName;
    public ushort ServiceCode;
};

SERVICE ByteArrayToService(byte[] array)
{
    GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
    SERVICE service = (SERVICE)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(SERVICE));
    handle.Free();
    return service;
}
0 голосов
/ 07 марта 2011

Исходя из вопроса, я не смог выяснить, как вы хотите этого добиться, но это структура C #.

Вы можете определить структуру как показано ниже

public struct Service
{

    public byte C;
    public byte Size;
    public byte HeadCode;
    public byte Type;
    public UInt16 Port;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
    public byte[] values;
    public UInt16 ServiceCode;

}
0 голосов
/ 07 марта 2011

Во-первых, решите, является ли ваша байтовая кодировка младшей или старшей.Затем распакуйте поля одно за другим (пример C)

struct SERVICE s;
int i = 0;
s.c = data[i++];
s.size = data[i++];
s.headcode = data[i++];
s.Type = data[i++];
s.Port = data[i++] << 8 | data[i++]; /* This is where endian matters */
memcpy(s.ServiceName, &data[i], 50);
i += 50;
s.ServiceCode = data[i++] << 8 | data[i++];

ПРИМЕЧАНИЕ. Обычно это записывается как перемещение указателя данных вместо использования «i» в качестве индекса, но я оставил его в этой форме для простотыперехода на C #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...