前言
前段时间心心念念的换了个岗位,本以为能够少些加班,多些时间逛逛论坛,写写文章,不抱有杂念的去享受学习的乐趣。然而需求虽迟但到,测试也如影随形,有些时候也很无奈,加班也成了默认的常态。
这两天刚刚看到一则新闻,人社部和最高法争议案例明确996工作制违法,gf的表态确实是一个很好的信号,可是真要普及怕是还有很长的路要走。回想起刚毕业那会儿本着到点就下班走人,有本事你就开除了我的心态,继而到现在的还有个需求没写完,今天提交完版本才能走的心境转换,从一开始的抵触到现在的默默接受,一方面是因为生活的压力不得不工作,一方面也是因为环境如此,没人能置身其外。
五点半下班那会儿我记得下班还能看到夕阳,那也是一天中为数不多的感受到自己不是一枚螺丝钉的时刻,如今下班只有空空的地铁等着。有时候也觉得自己的忍受力在不断的变高,也不知道这种变化是屈服妥协还是适应变强。
牢骚也只是牢骚,发完了还是要继续搬砖,努力让自己多学习一些新的东西,论坛的朋友们还请多多指教!
一、编码与解码
1、应用场景
最近遇到一个新需求,场景有多个客户(B端)向一台服务器(某个权威机构)发送请求并且接收应答。现在该服务器在接收到客户A的请求后会将应答广播推送至所有客户端,每一个客户端需要识别出自己的请求应答。网络消息只设计了一个字段用于识别,一个requestid,即客户端发送的请求id会被填写到rsp中返回。
大家应该能看出来这个实现有多么蛋疼,但是作为一个客户端没有办法去更改该机构的设计,即使他不合理。
-
方案一,为了解决这个问题,前员工提出了一套解决方案,限定我方客户端发出的requestid范围,比如说大于100万的就认为是我方发出的请求。没错,这个方案在没有和所有客户端沟通严格划分区间的时候是一定会出问题的,现实是这种协调不具有可行性。
-
方案二,对于该requestid进行特殊的编解码,使其成为我司独特的编码。
2、解决方案
针对于一个int型的数字进行编码,首先考虑到int32具有四个字节,每一个字节8bit。采用最高位两字节形成独特的识别码,低位两字节递增形成不同的requestid。requestid在实际应用中为正值,采用unsigned类型,2的16次方也就是65536,基本上能够满足应用需求。
在编码的过程中需要使用到c++中的按位运算、移位运算、进制转换等基础知识。
3、设计思路
3.1 标志位的确定
对于最高的两字节,我们选择具有公司或者部门标识的两个unsigned char值,每一个数值占用8个bit,利用ascll编码赋值,此处例如我们的标识符是GG:
unsigned char bytesOne = 'G';
unsigned char bytesTwo = 'G';
进制转换:
3.2 编解码过程
如何将两个char拼接到一个int里面呢?
采用按位或和移位操作相结合的方式,
unsigned int result = 0;
result = bytesOne;
result <<= 8;
result |= bytesTwo;
result <<= 16;
- 首先定义一个默认值为0的int类型result,我们将bytesone赋值给result,将result算数左移8位,这样我们就在result的第8-15个字节处赋值为‘G’了; 第二个字节的拼接也是一样的道理,这样我们的最高两个bytes就已经处理好了。
- 低位两个bytes就采用一个工具函数,根据输入的int截取低位,拼接到前面的结果那么我们的一个编码过程就已经实现了。
具体实现如下图:
在接收到返回的response时,我们获取到的requestid需要一个解码的过程,我们需要识别出该数字的标志位是否与我们设计的符号位一致。采取的方案是截取最高两个字节,与我们的标志位构造出的result比较,相等的话就可以很大概率上视为我们发出的消息得到的应答了。
获取标志位的的过程如下:
为什么说是大概率呢?
其实其他客户端发送的请求id也是有一定概率会和我们发出的requestid标志位一致的,但是方案二已经对比方案一改进了很多,其实根本上来讲,应该添加一个字段存储枚举值来区别各个客户端,这才是更为准确的解决方案。
二、编码解码代码实现
- encoding.h
#pragma once
class RequestidEncoding {
public:
RequestidEncoding() {}
~RequestidEncoding() {}
unsigned int GetForcecloseRequestid(unsigned int requestid);
bool IsForcecloseOrder(unsigned int requestid);
unsigned int GetFlag();
unsigned int GetTheLowestTwoBytes(unsigned int requestid);
unsigned int GetTheHighestTwoBytes(unsigned int requestid);
private:
//wait to develop
unsigned char bytesOne = 'G';
unsigned char bytesTwo = 'G';
};
- encoding.cpp
#include "encoding.h"
unsigned int RequestidEncoding::GetForcecloseRequestid(unsigned int requestid) {
unsigned int result = 0;
result = bytesOne;
result <<= 8;
result |= bytesTwo;
result <<= 16;
result |= GetTheLowestTwoBytes(requestid);
return result;
}
bool RequestidEncoding::IsForcecloseOrder(unsigned int requestid) {
unsigned int highBytes = GetTheHighestTwoBytes(requestid);
unsigned int Flag = GetFlag();
if (highBytes == Flag)
{
return true;
}
else
{
return false;
}
}
unsigned int RequestidEncoding::GetFlag() {
unsigned int result = 0;
result = bytesOne;
result <<= 8;
result |= bytesTwo;
result <<= 16;
return result;
}
unsigned int RequestidEncoding::GetTheLowestTwoBytes(unsigned int requestid) {
unsigned int result = 0x0000FFFF;
result &= requestid;
return result;
}
unsigned int RequestidEncoding::GetTheHighestTwoBytes(unsigned int requestid) {
unsigned int result = 0xFFFF0000;
result &= requestid;
return result;
}
❤️❤️❤️ 如果本文对你有所帮助,请不要忘了点赞、关注、收藏哦!灰常感谢! ❤️❤️❤️