MQTT 协议剩余长度计算C#版

MQTT Version 5.0

中固定头部中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 { }
        }

        /// <summary>
        /// 把给定长度转成Mqtt 固定头部剩余长度字节
        /// </summary>
        /// <param name="length"></param>
        /// <returns></returns>
        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;
            }
        }


        /// <summary>
        /// 把MQTT 剩余长度的16进制格式转化对应的10进制数值
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnHexTo10_Click(object sender, EventArgs e)
        {
            try
            {
                string[] hexRaw = this.txtHexValue.Text.Split(' ');//低位在前             
                int result = 0;
                for (int i = 0; i <hexRaw.Length; 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
            { }
        }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值