当前位置: 首页 > news >正文

FAST协议详解1 不同数据类型的编码与解码

一、概述

FAST协议里不同的数据类型在编码时有非常大的区别,比如整数只需要将二进制数据转为十进制即可,而浮点数则需要先传小数点位数,再传一个整数,最后将二者结合起来才是最终结果。本篇使用openfast自设了一些数据并编码成FAST数据,再对这些FAST数据进行人工解码,以图看懂FAST协议是如何传递不同类型的数据。

二、数据类型

看接口文档,存在以下类型的数据:

数据类型

说明

备注

ascii

ASCII字符串类型

byteVector

字节向量类型

decimal

浮点数类型

int16

有符号整数

都是有符号整数,区别仅在于取值范围

int32

有符号整数

int64

有符号整数

int8

有符号整数

string

字符串

uInt16

无符号整数

都是无符号整数,区别仅在于取值范围

uInt32

无符号整数

uInt64

无符号整数

uInt8

无符号整数

浓缩一下:

数据类型

说明

备注

ascii

ASCII字符串类型

string

字符串

byteVector

字节向量类型

decimal

浮点数类型

int

有符号整数

uInt

无符号整数

三、不同数据类型的编码与解码

1、ASCII字符串类型

使用上述代码输出为:

msg111= -> {123, 234}

outByteStr=11100000,11111011,00110010,00110011,10110100,

二进制数据解析如下:

二进制数

解码过程

解码结果

11100000

PMap

11111011

01111011=123

123

00110010,00110011,10110100

00110010=50=’2’

00110011=51=’3’

00110100=52=’4’

124

2、String字符串类型

使用上述代码输出为:

msg111= -> {123, 234}

outByteStr=11100000,11111011,00110010,00110011,10110100,

二进制数据解析如下:

二进制数

解码过程

解码结果

11100000

PMap

11111011

01111011=123

123

00110010,00110011,10110100

00110010=50=’2’

00110011=51=’3’

00110100=52=’4’

124

ASCII与string编码、解码一致,看不出区别。

3、int有符号整数类型

使用上述代码输出为:

msg111= -> {123, 234}

outByteStr=11100000,11111011,00000001,11101010,

二进制数据解析如下:

二进制数

解码过程

解码结果

11100000

PMap

11111011

01111011=123

123

00000001,11101010

00000001=1*128=128

01101010=106

128+106=234

234

将输入修改为负值

msg111= -> {123, -234}

outByteStr=11100000,11111011,01111110,10010110

二进制数据解析如下:

二进制数

解码过程

解码结果

11100000

PMap

11111011

01111011=123

123

01111110,10010110

01111110->1111110

10010110->0010110

实际:11111100010110

=-234

234

问题:有符号整数如何传输负值?

可以看到,在传输234这个值时,我们解码的方式是将2个字节分开,前面的字节转十进制后乘以128,后面的字节直接转十进制,然后两个十进制数相加。

在传输-234时,是两个字节分别去掉第一个位(停止位),拼接起来直接转成了十进制。

我们知道,在计算机中,对于有符号整数的二进制存储,是默认了,第一个位是1的话认为是负数,第一个位是0的话则认为是正数。这里也是一样,去掉每个字节的第一个位(停止位)后,第一个位如果是1则认为是负数,适用负数转换规则。第一个位如果是0则认为是正数,适用正数转换规则。

对于一些数值,刚好第一位是1该如何处理,比如126=1111110?

msg111= -> {123, 126}

outByteStr=11100000,11111011,00000000,11111110,

实例如上,只需要在前面补0即可。

4、uInt无符号类型

使用上述代码输出为:

msg111= -> {123, 126}

outByteStr=11100000,11111011,11111110,

二进制数据解析如下:

二进制数

解码过程

解码结果

11100000

PMap

11111011

01111011=123

123

11111110

01111110=126

126

可见,对于无符号数,直接按正数规则解码即可。

5、decimal浮点数类型

使用上述代码输出为:

msg111= -> {123, 234.456}

outByteStr=11100000,11111011,11111101,00001110,00100111,11011000,

二进制数据解析如下:

二进制数

解码过程

解码结果

11100000

PMap

11111011

01111011=123

123

11111101

11111101=-3

-3

00001110,00100111,11011000

00001110=14

00100111=39

01011000=88

14*128*128+39*128+88=234456

234456

很容易看明白,对浮点数进行编码时分成了2个部分,第一部分是“小数点”位数,第二部分是整数。解码后将两部分合并才能得到最终结果。

问题:如何传递负浮点数?

将234.456修改为-234.456后,输出为:

msg111= -> {123, -234.456}

outByteStr=11100000,11111011,11111101,01110001,01011000,10101000,

二进制数据解析如下:

二进制数

解码过程

解码结果

11100000

PMap

11111011

01111011=123

123

11111101

11111101=-3

-3

01110001,01011000,10101000

111000110110000101000=-234456

-234456

与有符号整数差不多,是否传递负数,只需要将除去“停止位”后,判断第一个位是否是“1”即可。所以只需要将浮点数的传递看成是“小数点”+“整数”两个部分即可。

6、byteVector字节向量类型

前面我们讨论了整数、浮点数、字符串,所有的编码其实都遵循了一个原则,即一个字节能够传递的最大值只能小于128,要传递更大的值则需要“进位”。但我们需要传递的字节一定要大于128该如何是好,比如中文。我们使用前面的字符串、ASCII、整数,也不是不能编码,但解码起来就有点麻烦。很明显这时候就可以用到字节向量。

使用上述代码输出为:

msg111= -> {123, ????????}

outByteStr=11100000,11111011,10001000,11001110,11111011,11001110,11111011,10111001,11111110,10111001,11111110,

二进制数据解析如下:

二进制数

解码过程

解码结果

11100000

PMap

11111011

01111011=123

123

10001000

00001000=8

8个字节

11001110,11111011,

11001110,11111011,

10111001,11111110,

10111001,11111110

11001110,11111011=CE FB

11001110,11111011=CE FB

10111001,11111110=B9 FE

10111001,11111110=B9 FE

CEFB CEFB B9FE B9FE=嘻嘻哈哈

嘻嘻哈哈

有点类似浮点数的编码,这里先传递字节向量的长度“8”,接着传递字节向量。由于字节向量的长度已指定,故传输数据时不再遵循停止位的概念。

另注意这里使用的是GBK编码,故直接输出是乱码。

四、回顾

数据类型

说明

备注

ascii

ASCII字符串类型

遵循一般停止位规则,最后一个字节的第一位为1则是该字段最后一个字节,而后根据ASCII码表直接转字符串即可。

string

字符串

同上

int

有符号整数

遵循一般停止位规则,注意第一位(除开停止位之外的)为“0”则是正整数,则按128进位的规则进行数值转换即可。第一位(除开停止位之外的)为“1”则是负整数,则将全部字节去掉停止位后,直接转为整数即可。负数转换时需要注意前面要补1。

uInt

无符号整数

遵循一般停止位规则,由于知道一定是正整数,则直接按128进位的规则进行数值转换即可。

decimal

浮点数类型

分两部分进行传递,两个部分均遵循一般停止位规则。第一部分是浮点数的“小数点位数”,第二部分则是整数。注意是有符号整数,遵循int的解码方式即可。

byteVector

字节向量类型

分两部分进行传递,第一部分是字节向量的长度,遵循一般停止位规则。第二部分则是纯byte数据,不再遵循停止位规则,但由于前面有传递其长度,故也不会出错。

结语:这里只是最基本的编码解码规则,到这里也只是能稍微看懂一点还无法进行真正的FAST解码。后面的“操作符”及null什么的才是硬骨头。

http://www.lryc.cn/news/113591.html

相关文章:

  • 黑马大数据学习笔记5-案例
  • 网络编程——TCP/IP协议族(IP协议、TCP协议和UDP协议……)
  • Oracle SQL存储过程能够返回表吗
  • 2 Vue使用v-bind来代替{{}}取值
  • 20230807在WIN10下使用python3将TXT文件转换为DOCX(在UTF8编码下转换为DOCX有多一行的瑕疵)
  • Flutter(八)事件处理与通知
  • Java,python,c#,js,c++搞量化交易的接口大全
  • javaAPI(一):String
  • 数据互通,版本管理优化图文档与BOM数据
  • 【CSS】旋转中的视差效果
  • 【ASP.NET MVC】使用动软(一)(9)
  • 【Jsp课设】3款基于JavaWeb的学生选课管理系统
  • 系统架构设计师笔记第35期:表现层框架设计
  • 力扣 -- 467. 环绕字符串中唯一的子字符串
  • Hi3798MV200 恩兔N2 NS-1 (四): 制作 Debian rootfs
  • 面试热题(字符串相加)
  • 我的创作纪念日【第一个2048day】
  • 内网穿透-————SSH远程连接树莓派
  • 一键开启ChatGPT“危险发言”
  • RISC-V基础之函数调用(一)简单的函数调用(包含实例)
  • apt、aptitude、apt-get/apt-cache语法的区别
  • 华为认证 | HCIA和HCIP有啥区别?
  • JavaScript基础知识
  • vue2 todoapp案例(静态)
  • qt5.14 和 qt5.15的区别
  • 如何使用自己域名进行远程访问内网群晖NAS 6.X
  • PHP判处重复延长队列执行时间
  • flask中的应用上下文
  • cocos creator 的input.on 不生效
  • WFPlayer