将字节组合成逻辑值
Combining bytes into logical values
我正在以(预期的)以下格式取回数据:
\u0001\u0001\u0004[=10=]\u0001[=10=][=10=][=10=]
每个段代表一个字节。前两段\u0001\u0001
代表服务版本号,后两段\u0004[=13=]
代表状态码,最后4u0001[=14=][=14=][=14=]
代表请求id。
如何将我知道的字段组合在一起并从结果中得出逻辑值?例如,状态码 \u0004[=13=]
应该是一个 signed-short 并且请求 id 应该是一个 int.
我玩过但不知道有效性的东西:
byte s1 = 0004;
byte s2 = 0;
short statusCode = (short)(s1 | (s2 << 8));
byte r1 = 0001;
byte r2 = 0;
byte r3 = 0;
byte r4 = 0;
int requestId = (int)(r1 | (r2 << 8) | (r3 << 16) | (r4 << 24));
虽然您的逻辑看起来不错,但手动位移可能会变得非常乏味,尤其是当您必须处理的数据量增加时。对于 8 个字节来说已经足够简单了,但是对于其他所有内容,我建议您直接研究将字节编组到对象中。
为此,定义一个值类型来解释您的数据:
public struct Data
{
public short serviceVersion;
public short statusCode;
public int requestId;
}
然后,您可以将字符串转换为字节数组,并将其编组为 Data
对象:
// raw input, as a string
string s = "\u0001\u0001\u0004[=11=]\u0001[=11=][=11=][=11=]";
// convert string into byte array
byte[] bytes = Encoding.UTF8.GetBytes(s);
// interpret byte array as `Data` object
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
Data data = (Data)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Data));
handle.Free();
// access the data!
Console.WriteLine(data.serviceVersion); // 257
Console.WriteLine(data.statusCode); // 4
Console.WriteLine(data.requestId); // 1
扩展@poke 上面的 post;如果你想变得非常花哨,你可以做一个 union
类似的效果
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct Data
{
[FieldOffset(0)]
public short serviceVersion;
[FieldOffset(2)]
public short statusCode;
[FieldOffset(4)]
public int requestId;
[FieldOffset(0)]
public ulong Value;
}
使用 Data.Value
字段读取您关心的所有位。
此外,使用 unsafe
可以避免编组。
// raw input, as a string
string s = "\u0001\u0001\u0004[=11=]\u0001[=11=][=11=][=11=]";
// convert string into byte array
byte[] bytes = Encoding.UTF8.GetBytes(s);
Data data = new Data();
unsafe
{
Data* d = &data;
fixed(byte* b = bytes)
{
*d = *((Data*)b);
}
}
我正在以(预期的)以下格式取回数据:
\u0001\u0001\u0004[=10=]\u0001[=10=][=10=][=10=]
每个段代表一个字节。前两段\u0001\u0001
代表服务版本号,后两段\u0004[=13=]
代表状态码,最后4u0001[=14=][=14=][=14=]
代表请求id。
如何将我知道的字段组合在一起并从结果中得出逻辑值?例如,状态码 \u0004[=13=]
应该是一个 signed-short 并且请求 id 应该是一个 int.
我玩过但不知道有效性的东西:
byte s1 = 0004;
byte s2 = 0;
short statusCode = (short)(s1 | (s2 << 8));
byte r1 = 0001;
byte r2 = 0;
byte r3 = 0;
byte r4 = 0;
int requestId = (int)(r1 | (r2 << 8) | (r3 << 16) | (r4 << 24));
虽然您的逻辑看起来不错,但手动位移可能会变得非常乏味,尤其是当您必须处理的数据量增加时。对于 8 个字节来说已经足够简单了,但是对于其他所有内容,我建议您直接研究将字节编组到对象中。
为此,定义一个值类型来解释您的数据:
public struct Data
{
public short serviceVersion;
public short statusCode;
public int requestId;
}
然后,您可以将字符串转换为字节数组,并将其编组为 Data
对象:
// raw input, as a string
string s = "\u0001\u0001\u0004[=11=]\u0001[=11=][=11=][=11=]";
// convert string into byte array
byte[] bytes = Encoding.UTF8.GetBytes(s);
// interpret byte array as `Data` object
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
Data data = (Data)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Data));
handle.Free();
// access the data!
Console.WriteLine(data.serviceVersion); // 257
Console.WriteLine(data.statusCode); // 4
Console.WriteLine(data.requestId); // 1
扩展@poke 上面的 post;如果你想变得非常花哨,你可以做一个 union
类似的效果
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit, Size = 8)]
public struct Data
{
[FieldOffset(0)]
public short serviceVersion;
[FieldOffset(2)]
public short statusCode;
[FieldOffset(4)]
public int requestId;
[FieldOffset(0)]
public ulong Value;
}
使用 Data.Value
字段读取您关心的所有位。
此外,使用 unsafe
可以避免编组。
// raw input, as a string
string s = "\u0001\u0001\u0004[=11=]\u0001[=11=][=11=][=11=]";
// convert string into byte array
byte[] bytes = Encoding.UTF8.GetBytes(s);
Data data = new Data();
unsafe
{
Data* d = &data;
fixed(byte* b = bytes)
{
*d = *((Data*)b);
}
}