FAST协议解析1 通过输入输出逆解析

一、前言

FAST协议可以支持金融机构间高吞吐量、低延迟的数据通讯,目前我知道的应用领域是沪深交易所的Level-2行情传输。网络上无论是FAST协议本身,还是使用相关工具(openfast、quickfast)对FAST行情进行解析,相关的资料都是凤毛麟角,能够找到本篇的同学那是缘分不浅了。

如果要理解FAST协议,建议还是先用会openfast或quickfast,先用现成的工具实现数据的编码和解码,然后再自己理解协议并手写编码解码,简单来说就是有个对照。我这里使用的是openfast。

二、openfast的编码与解码

如果想了解openfast如何解析FAST数据的完整示例,可以参考我之前的博文。这里我们先简单回顾一下openfast的编码和解码。

完整代码下载:https://share.weiyun.com/jQseMppi

1、消息模版

如下图所示,我们借用UA3815这个消息模版。

2、编码、解码

如下图所示,使用openfast自己先编码再解码,我是参考的一条真实UA3815消息的FAST数据。

输出结果如下,第一行是FAST消息解码结果(解码验证),第二行是将FAST数据按byte输出(编码验证)。

实验结果证明编码与解码的结果符合预期。实际上我也对FAST的byte输出进行了验证,与实际的收到的FAST数据是一致的。

三、openfast逆解析

我找了不少文档看,是真的看不明白,最后想到既然有openfast这个工具,为啥不利用工具来逆解析呢?事实证明效果非常好,而FAST协议真的很简单。下面我们直接来看结果。

1、示例代码

对模版和代码进行修改简化。

代码这里只是做个修改的示例,后面的修改不再赘述。

2、一个int32

下图分别是对空数据、0、1、2、3...256进行FAST编码后的结果,将其转为2进制后可以看到非常明显的规律。

规律一:FAST编码后的数据可以分为三个区域

如下图所示。而且区域三很明显是数值部分,也就是对int 0 FAST编码后的结果就是1000 0000。对256编码的结果就是0000 0010 1000 0000。接着我们就能发现下一个规律。

规律二:数值部分是128进制

也就是每一段(一个byte)满128向前进一位。

127-> 0000 0000, 1111 1111

128-> 0000 0001, 1000 0000

对于更大的数,则是128*128=16384进一位,这时候就需要第三段。

16383-> 0000 0000, 0111 1111, 1111 1111

16384-> 0000 0001, 0000 0000, 1000 0000

以此类推,如果是大于等于128*128*128=2097152,则需要第四段

2097152-> 0000 0001, 0000 0000, 0000 0000, 1000 000

3、两个int32

我们修改代码,这次输入2个int32值看下FAST编码的结果。

规律三:每一个byte的第一位是“分隔符”(停止位)

这里的分隔不仅将不同区域分隔,同一区域的不同字段也使用首位的“1”来分隔。

规律四:区域一标识了当前有多少个字段。

区域一的值:

空-> 1100 0000

一个数值字段-> 1110 0000

两个数值字段-> 1111 0000

我试了下14个数值字段:0111 1111,0111 1111,1100 0000

如下图,区域一标识了区域二(占一位),区域三(有多少个字段就标识多少个1)。同时区域一还遵循了规律三。

4、修改模版ID

输出结果:

规律五:区域二标识的是注册的模版ID,但与模版文件里的ID无关系。

5、数值类型

做沪市FAST行情解析,目前来看只用到了int32、int64、string三种类型,我们各放一个字段试试。

修改模版:

修改代码:

输出结果:

可以看到,int32和int64在FAST编码时无区别。

String则是直接转成了ASCII码:55->7、56->8、(185-128)=57->9

四、FAST编码解码基本规则

综上,我们通过openfast的使用,对FAST编码解码规则有了一些较为浅显的理解,现结合官方文档(https://jettekfix.com/education/fix-fast-tutorial/)总结如下:

规则一:FAST数据可分为三个区域,区域一是PMap字段(存在图),作用是标识出消息中的字段数量。区域二是模版ID字段,作用是标识出你注册的模版ID号,但这个ID与模版文件中的ID无关系。区域三是数值部分,可由多个字段顺序组成。

规则二:字段大小可变,通过对“停止位”的使用,将每个字节的第一位置为0或1以标识出该字段是否结束。其中0表示未结束,1表示结束。

规则三:数值需要按byte去掉第一位的0或1再来算值。Int类型直接二进制转整数,string类型则是二进制先转整数再由ASCII码表转字符。

五、回顾

本篇我们利用openfast来逆解析FAST协议,这么做之前,看相关文档资料即使是中文的也看不明白,但自己尝试了一下之后,发现即使是英文文档也能看明白了。

但目前只是总结了一些基本规律,看文档发现,还有很多知识点在模版上,后面再花时间研究了。关于这部分,可能直接翻译官方文档并使用openfast验证比较好。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然,我可以为您提供一个使用 FastAPI 创建一个开放接口的示例代码。以下是一个简单的示例,演示了如何使用 FastAPI 创建一个接收位置输入并返回输出数据的接口: ```python from fastapi import FastAPI app = FastAPI() @app.get("/weather/{location}") def get_weather(location: str): # 根据位置获取天气数据的逻辑 weather_data = fetch_weather_data(location) return {"location": location, "weather": weather_data} def fetch_weather_data(location: str): # 这里是根据位置获取天气数据的逻辑,这里仅作示例,可以根据实际需求进行实现 # 可以调用第三方天气API,或者从数据库中获取天气数据等 # 在这个示例中,我们只返回一个伪造的天气数据 weather_data = { "temperature": 25, "humidity": 75, "description": "Sunny" } return weather_data ``` 在这个示例中,我们创建了一个 `/weather/{location}` 的路由,接受一个名为 `location` 的路径参数。在 `get_weather` 函数中,我们根据传入的位置参数调用 `fetch_weather_data` 函数来获取天气数据。在 `fetch_weather_data` 函数中,您可以根据实际需求实现获取天气数据的逻辑(例如调用第三方天气 API 或从数据库中获取)。 当用户访问 `/weather/{location}` 路径时,FastAPI 会自动解析路径参数,并将其传递给相应的函数。然后,我们将位置参数和天气数据一起包装在一个 JSON 响应中返回。 请注意,这只是一个简单的示例,您可以根据您的实际需求进行扩展和优化。希望对您有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值