中固定头部中byte2 标识包的剩余长度, 单个byte最大能表示127的包长度,最高为标识位,1代表借用后续字节来标识包长度。
Table 1‑1 Size of Variable Byte Integer
Digits | From | To |
1 | 0 (0x00) | 127 (0x7F) |
2 | 128 (0x80, 0x01) | 16,383 (0xFF, 0x7F) |
3 | 16,384 (0x80, 0x80, 0x01) | 2,097,151 (0xFF, 0xFF, 0x7F) |
4 | 2,097,152 (0x80, 0x80, 0x80, 0x01) | 268,435,455 (0xFF, 0xFF, 0xFF, 0x7F) |
协议文档给出了算法如下:
The algorithm for encoding a non-negative integer (X) into the Variable Byte Integer encoding scheme is as follows:
- do
- encodedByte = X MOD 128
- X = X DIV 128
- // if there are more data to encode, set the top bit of this byte
-
- if (X > 0)
- encodedByte = encodedByte OR 128
- endif
- 'output' encodedByte
- while (X > 0)
Where MOD is the modulo operator (% in C), DIV is integer division (/ in C), and OR is bit-wise or (| in C).
The algorithm for decoding a Variable Byte Integer type is as follows:
- multiplier = 1
- value = 0
- do
- encodedByte = 'next byte from stream'
- value += (encodedByte AND 127) * multiplier
- if (multiplier > 128*128*128)
- throw Error(Malformed Variable Byte Integer)
- multiplier *= 128
- while ((encodedByte AND 128) != 0)
where AND is the bit-wise and operator (& in C).
When this algorithm terminates, value contains the Variable Byte Integer value.
利用C# 来写为:
-
- private void btn10toHex_Click(object sender, EventArgs e)
- {
- try
- {
- int num = int.Parse(this.txtDeciValue.Text);
- byte[] bytes = ConvertLength2MqttByte(num);
- string result= BytesConverter.ToHexString(bytes);
- this.txtHexValueCvt.Text = result;
- this.txtHexValue.Text = result;
- }
- catch { }
- }
-
- ///
- /// 把给定长度转成Mqtt 固定头部剩余长度字节
- ///
- ///
- ///
- byte[] ConvertLength2MqttByte(int length)
- {
- try
- {
- int encodeByte = 0;//需编码输出的数
- int dec = 128;//进制数,二进制为 1000 0000
- int reminder = length;
- do
- {
- //取num 的结束字节,高1位是符号位
- int lastEncodeByte = reminder % dec;
- reminder = reminder / dec;// 取余数
- if (reminder > 0)//需向高位进位
- {
- lastEncodeByte |= dec;// 高位符号位 填充1
- lastEncodeByte <<= 8;
- encodeByte <<= 8;//左移动8位,留给低字节
- }
- encodeByte |= lastEncodeByte;//填充低字节
- } while (reminder > 0);
-
- byte[] bytes = BitConverter.GetBytes(encodeByte);
- Array.Reverse(bytes);
- List<byte> targetBytes = new List<byte>();
- targetBytes.AddRange(bytes);
- var outputArray = targetBytes.Where(x => x > 0);
- return outputArray.ToArray();
- }
- catch
- {
- return null;
- }
- }
-
-
- ///
- /// 把MQTT 剩余长度的16进制格式转化对应的10进制数值
- ///
- ///
- ///
- private void btnHexTo10_Click(object sender, EventArgs e)
- {
- try
- {
- string[] hexRaw = this.txtHexValue.Text.Split(' ');//低位在前
- int result = 0;
- for (int i = 0; i
- {
- int mutiplier = 1;
- for (int j = 0; j < i; j++)
- {
- mutiplier *= 128;
- }
- byte num = Convert.ToByte(hexRaw[i], 16);
- byte temp = (byte)(num << 1);
- byte leftNum = (byte)(temp >> 1);
- result += leftNum * mutiplier;
- }
- this.txtDeciCvt.Text = result.ToString();
- }
- catch
- { }
- }
-