开发者

C# getting info from hexadecimal data

I have this hexadecimal data:

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, 0开发者_运维技巧x00, 0x00
};

I have C++ struct:

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

My question is: How to get from data ServiceName, Port and etc...?

Sorry for my bad english


Here is one way to do it:

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);
}

This assumes, that the binary array uses the same Endianess as your architecture. If that is not the case you can use the EndianBinaryReader from the MiscUtil library.

Edit: this is also a nice solution, that avoids the reader altogether. You can't directly specify the encoding to use for the string however and the memory layout of the structure has to match the layout used in the byte array.

[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;
}


First, Decide if your byte encoding is little or big endian. Then, unpack fields one by one (C example)

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++];

NOTE: This is usually written as moving the data pointer instead of using "i" as an index, but I left it in this form for ease of moving to C#.


From the question, I could not find out how you want to achieve this but this is the C# structure.

You can define the structure as below

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜