C#中基于byte[2]存储类型与大小信息的实现咨询
在C#中用两个字节(byte[2])存储类型与大小信息的实现
刚好做过类似的字节位操作需求,这就给你整理出完整的编码和解码逻辑,附带示例验证:
核心规则回顾
先明确你的需求细节,避免理解偏差:
- 第一个字节的高4位:存储0-9的类型值(占4位,刚好能容纳0-9)
- 第一个字节的低4位 + 第二个字节:存储0-4095的大小值(总共12位,最大值2^12-1=4095,完美匹配)
编码实现(将类型+大小转为byte[2])
先写一个方法,输入类型和大小,输出对应的两个字节:
public static byte[] EncodeData(int type, int size) { // 参数合法性校验 if (type < 0 || type > 9) throw new ArgumentOutOfRangeException(nameof(type), "类型值必须在0-9之间"); if (size < 0 || size > 4095) throw new ArgumentOutOfRangeException(nameof(size), "大小值必须在0-4095之间"); byte[] result = new byte[2]; // 第一个字节:高4位是类型,低4位是大小的高4位 result[0] = (byte)((type << 4) | ((size >> 8) & 0x0F)); // 第二个字节:大小的低8位 result[1] = (byte)(size & 0xFF); return result; }
编码逻辑拆解
type << 4:把类型值左移4位,放到第一个字节的高4位(比如类型5,左移4位后变成0x50)(size >> 8) & 0x0F:取出大小值的高4位(比如大小963=0x3C3,右移8位后是0x3,和0x0F与确保只取4位)- 用
|运算符把这两部分合并成第一个字节 size & 0xFF:直接取出大小值的低8位作为第二个字节
解码实现(将byte[2]转回类型+大小)
再写一个反向解码的方法:
public static (int type, int size) DecodeData(byte[] data) { if (data == null || data.Length != 2) throw new ArgumentException("输入必须是长度为2的字节数组"); // 从第一个字节高4位取类型 int type = data[0] >> 4; // 从第一个字节低4位+第二个字节取大小 int size = ((data[0] & 0x0F) << 8) | data[1]; return (type, size); }
解码逻辑拆解
data[0] >> 4:把第一个字节右移4位,直接得到高4位的类型值(比如第一个字节是0x53,右移4位后是0x5,即类型5)(data[0] & 0x0F) << 8:取出第一个字节的低4位,左移8位后变成12位大小的高4部分- 和第二个字节做
|运算,拼接出完整的12位大小值
示例验证
用你给出的测试场景验证:
类型信息为5、大小为963
调用编码方法:
var bytes = EncodeData(5, 963); // 转换为十六进制字符串输出 string hexStr = $"{bytes[0]:X2}-{bytes[1]:X2}"; // hexStr的值为 "53-C3"
解码回去:
var (type, size) = DecodeData(bytes); // type=5,size=963,和输入一致
注:你提到的示例结果是35-C3,这和我们的计算结果有差异,推测是示例中的十六进制字节顺序写反了——53-C3才符合“类型5+大小963”的规则哦。
另一个测试场景:
03-00对应类型信息3
如果要得到类型3、大小0的结果,调用EncodeData(3,0)会得到字节数组0x30, 0x00,对应十六进制字符串30-00,推测你示例中的03-00是字节顺序写反了~
注意事项
- 一定要加参数合法性校验,避免超出范围的值导致位操作异常
- 字节是无符号类型(C#中
byte默认无符号),所以位操作时不需要考虑符号位问题 - 转换为十六进制字符串时,用
X2格式确保每个字节占两位,不足补0
内容的提问来源于stack exchange,提问作者mMilk
相关产品推荐
相关产品推荐

