• 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:

    1. do
    2.    encodedByte = X MOD 128
    3.    X = X DIV 128
    4.    // if there are more data to encode, set the top bit of this byte
    5.    if (X > 0)
    6.       encodedByte = encodedByte OR 128
    7.    endif
    8.    'output' encodedByte
    9. 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:   

    1. multiplier = 1
    2. value = 0
    3. do
    4.    encodedByte = 'next byte from stream'
    5.    value += (encodedByte AND 127) * multiplier
    6.    if (multiplier > 128*128*128)
    7.       throw Error(Malformed Variable Byte Integer)
    8.    multiplier *= 128
    9. 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# 来写为:

    1. private void btn10toHex_Click(object sender, EventArgs e)
    2. {
    3. try
    4. {
    5. int num = int.Parse(this.txtDeciValue.Text);
    6. byte[] bytes = ConvertLength2MqttByte(num);
    7. string result= BytesConverter.ToHexString(bytes);
    8. this.txtHexValueCvt.Text = result;
    9. this.txtHexValue.Text = result;
    10. }
    11. catch { }
    12. }
    13. ///
    14. /// 把给定长度转成Mqtt 固定头部剩余长度字节
    15. ///
    16. ///
    17. ///
    18. byte[] ConvertLength2MqttByte(int length)
    19. {
    20. try
    21. {
    22. int encodeByte = 0;//需编码输出的数
    23. int dec = 128;//进制数,二进制为 1000 0000
    24. int reminder = length;
    25. do
    26. {
    27. //取num 的结束字节,高1位是符号位
    28. int lastEncodeByte = reminder % dec;
    29. reminder = reminder / dec;// 取余数
    30. if (reminder > 0)//需向高位进位
    31. {
    32. lastEncodeByte |= dec;// 高位符号位 填充1
    33. lastEncodeByte <<= 8;
    34. encodeByte <<= 8;//左移动8位,留给低字节
    35. }
    36. encodeByte |= lastEncodeByte;//填充低字节
    37. } while (reminder > 0);
    38. byte[] bytes = BitConverter.GetBytes(encodeByte);
    39. Array.Reverse(bytes);
    40. List<byte> targetBytes = new List<byte>();
    41. targetBytes.AddRange(bytes);
    42. var outputArray = targetBytes.Where(x => x > 0);
    43. return outputArray.ToArray();
    44. }
    45. catch
    46. {
    47. return null;
    48. }
    49. }
    50. ///
    51. /// 把MQTT 剩余长度的16进制格式转化对应的10进制数值
    52. ///
    53. ///
    54. ///
    55. private void btnHexTo10_Click(object sender, EventArgs e)
    56. {
    57. try
    58. {
    59. string[] hexRaw = this.txtHexValue.Text.Split(' ');//低位在前
    60. int result = 0;
    61. for (int i = 0; i
    62. {
    63. int mutiplier = 1;
    64. for (int j = 0; j < i; j++)
    65. {
    66. mutiplier *= 128;
    67. }
    68. byte num = Convert.ToByte(hexRaw[i], 16);
    69. byte temp = (byte)(num << 1);
    70. byte leftNum = (byte)(temp >> 1);
    71. result += leftNum * mutiplier;
    72. }
    73. this.txtDeciCvt.Text = result.ToString();
    74. }
    75. catch
    76. { }
    77. }

     

  • 相关阅读:
    CSDN专栏设置
    SpringMVC的上传下载
    百度曹海涛:生成式AI正从“探索能力边界”向“推动应用落地”过渡
    论文解读(Geom-GCN)《Geom-GCN: Geometric Graph Convolutional Networks》
    RK3568核心板分区空间不足,如何修改分区大小?
    【韭菜拾遗】Coqui TTS: a deep learning toolkit for Text-to-Speech
    杰理之充电仓升级及 dut 测试功能【篇】
    [JVM]问下,对象在堆上的内存分配是怎样的
    20220701
    设计模式:中介者模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)
  • 原文地址:https://blog.csdn.net/elie_yang/article/details/126949891