目标
理解可变字节整数概念,即MQTT5.0 协议中的 “1.5.5 Variable Byte Integer”内容
介绍
MQTT中的“可变字节整数”其实是可变字节编码算法,用于对整数序列进行快速压缩。
在英文表达中常见的写法有:Variable byte codes,Variable-Byte Codes,Variable Encoding,Variable byte, varints
具体编解码算法实现,可具体参见“1.5.5 Variable Byte Integer”中的样例内容
相关文章
根据MQTT规范实践算法
实践数字序列
125,128,16385,2097152
实践日志
2023-09-01 15:52:07:718 编码前的数字序列为:125 128 16385 2097152
2023-09-01 15:52:07:718 编码后二进制: 1111101 10000000 1 10000001 10000000 1 10000000 10000000 10000000 1
2023-09-01 15:52:07:718 解码后的数字序列为:125 128 16385 2097152
Java算法代码
package com.harvey.mqtt;
import org.eclipse.paho.mqttv5.client.logging.HarveyDebug;
import java.io.ByteArrayOutputStream;
/**
*
* MQTT5.0 : https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.pdf
* 参见 "1.5.5 Variable Byte Integer" 内容
*
*/
public class ExampleVariableByteInteger {
public static void main(String[] args) {
ByteArrayOutputStream bais = new ByteArrayOutputStream();
int [] inNum = {125, 128, 16385, 2097152};
int x = 16385;
StringBuilder sbInNum = new StringBuilder();
sbInNum.append("编码前的数字序列为:");
StringBuilder sb = new StringBuilder();
for (int k : inNum){
x = k;
sbInNum.append(x).append(" ");
do{
int encodeByte = x % 128;
x = x / 128;
if ( x > 0){
encodeByte = (encodeByte | 128);
}
bais.write(encodeByte);
sb.append(Integer.toBinaryString(encodeByte)).append(" ");
} while ( x > 0);
}
HarveyDebug.d(sbInNum.toString());
HarveyDebug.d("编码后二进制: " + sb.toString());
HarveyDebug.d();
StringBuilder sbDecodeNum = new StringBuilder();
sbDecodeNum.append("解码后的数字序列为:");
byte [] covert = bais.toByteArray();
int index = 0;
do{
int multiplier = 1;
int value = 0;
int encodedByte = 0;
do{
encodedByte = covert[index];
value += (encodedByte & 127) * multiplier;
if(multiplier > 128*128*128){
System.err.println("非法编码");
break;
}
multiplier *= 128;
index++;
} while ((encodedByte & 128) != 0);
sbDecodeNum.append(value).append(" ");
} while (index < covert.length);
HarveyDebug.d(sbDecodeNum.toString());
}
}