新闻详情

新闻详情

首页 / 资讯中心 / 详情

一套模仿WhatsApp消息API的接口设计

发布时间:2026/9/3 12:42:45来源:尧图网络
一套模仿WhatsApp消息API的接口设计
背景前一段模仿WhatsApp Business的核心功能做了一套商业号服务,为了让老外看起来亲切,因此其接口设计尽量与WhatsApp保持一致,因此可以将此接口设计share出来,通过该接口设计,大家可以了解到WhatsApp Business的核心功能及其对应的接口定义;尽管如此,一些地方的设计也有小差异,例如:WhatsApp直接使用手机号码定位用户,在这套设计中则借鉴了微信公众号OpenUserId的套路,另外为了安全考虑对真实userId又进行了加入应用ID因子的混淆,因此可以做到:同一个用户不同应用(订阅号)下的OpenUserId不同,OpenUserId实现参考如下:ByteUtilpackagecodec;importorg.apache.commons.lang3.ArrayUtils;/** * ByteUtil * * @author chenx */publicclassByteUtil{publicstaticfinalintONE_BYTE_INT_MAX_VALUE=127;publicstaticfinalintONE_BYTE_INT_MIN_VALUE=-128;publicstaticfinalintTIMESTAMP_BYTES=6;privatestaticfinalStringINPUT_BYTES_LENGTH_MUST_MORE_THAN="The input bytes.length must =";privatestaticfinalStringINPUT_BYTES_LENGTH_MUST_BE="The input bytes.length must be ";privateByteUtil(){}/** * timestampToSixBytes * * @param timestamp * @return */publicstaticbyte[]timestampToSixBytes(longtimestamp){byte[]data=newbyte[TIMESTAMP_BYTES];data[0]=(byte)(timestamp40);data[1]=(byte)(timestamp32);data[2]=(byte)(timestamp24);data[3]=(byte)(timestamp16);data[4]=(byte)(timestamp8);data[5]=(byte)(timestamp0);returndata;}/** * sixBytesToTimestamp * * @param bytes * @return */publicstaticlongsixBytesToTimestamp(byte[]bytes){if(ArrayUtils.isEmpty(bytes)||bytes.lengthTIMESTAMP_BYTES){thrownewIllegalArgumentException(INPUT_BYTES_LENGTH_MUST_MORE_THAN+TIMESTAMP_BYTES);}return(((long)(bytes[0]255)40)+((long)(bytes[1]255)32)+((long)(bytes[2]255)24)+((bytes[3]255)16)+((bytes[4]255)8)+((bytes[5]255)0));}/** * short2Bytes * * @param num * @return */publicstaticbyte[]short2Bytes(shortnum){byte[]bytes=newbyte[Short.BYTES];bytes[0]=(byte)(num8);bytes[1]=(byte)num;returnbytes;}/** * bytes2Short * * @param bytes * @return */publicstaticshortbytes2Short(byte[]bytes){if(ArrayUtils.isEmpty(bytes)||bytes.length!=Short.BYTES){thrownewIllegalArgumentException(INPUT_BYTES_LENGTH_MUST_BE+Short.BYTES);}return(short)((bytes[0]8)|(bytes[1]0xFF));}/** * int2Bytes * * @param num * @return */publicstaticbyte[]int2Bytes(intnum){byte[]byteNum=newbyte[Integer.BYTES];for(intix=0;ixInteger.BYTES;++ix){intoffset=32-(ix+1)*8;byteNum[ix]=(byte)((numoffset)0xff);}returnbyteNum;}/** * bytes2Int * * @param bytes * @return */publicstaticintbytes2Int(byte[]bytes){if(ArrayUtils.isEmpty(bytes)||bytes.length!=Integer.BYTES){thrownewIllegalArgumentException(INPUT_BYTES_LENGTH_MUST_BE+Integer.BYTES);}intnum=0;for(intix=0;ixInteger.BYTES;++ix){num=8;num|=(bytes[ix]0xff);}returnnum;}/** * long2Bytes * * @param num * @return */publicstaticbyte[]long2Bytes(longnum){byte[]byteNum=newbyte[Long.BYTES];for(intix=0;ixLong.BYTES;++ix){intoffset=64-(ix+1)*8;byteNum[ix]=(byte)((numoffset)0xff);}returnbyteNum;}/** * bytes2Long * * @param bytes * @return */publicstaticlongbytes2Long(byte[]bytes){if(ArrayUtils.isEmpty(bytes)||bytes.length!=Long.BYTES){thrownewIllegalArgumentException(INPUT_BYTES_LENGTH_MUST_BE+Long.BYTES);}longnum=0;for(intix=0;ixLong.BYTES;++ix){num=8;num|=(bytes[ix]0xff);}returnnum;}/** * mergeBytes * * @param arrays * @return */publicstaticbyte[]mergeBytes(byte[]...arrays){inttotalLength=0;for(byte[]array:arrays){totalLength+=array.length;}byte[]result=newbyte[totalLength];intcurrentIndex=0;for(byte[]array:arrays){System.arraycopy(array,0,result,currentIndex,array.length);currentIndex+=array.length;}returnresult;}/** * getBytesFromStart * * @param array * @param length * @return */publicstaticbyte[]getBytesFromStart(byte[]array,intlength){if(ArrayUtils.isEmpty(array)){thrownewIllegalArgumentException("the input bytes is empty!");}if(length=0){thrownewIllegalArgumentException("The length must 0!");}if(array.lengthlength){thrownewIllegalArgumentException("the input bytes.length must "+length+"!");}byte[]result=newbyte[length];System.arraycopy(array,0,result,0,length);returnresult;}/** * obfuscateBytes * * @param bytes * @param hashBytesLength */publicstaticvoidhashObfuscate(byte[]bytes,inthashBytesLength){if(hashBytesLength=0){thrownewIllegalArgumentException("invalid hashLength!");}if(ArrayUtils.isEmpty(bytes)||bytes.length=hashBytesLength){thrownewIllegalArgumentException("bytes.length = "+hashBytesLength);}intleftBytesSize=bytes.length-hashBytesLength;byte[]hashBytes=newbyte[hashBytesLength];byte[]leftBytes=new
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

《华恒智信参与某文旅集团半年经营分析会》 2026/9/3 13:18:52

《华恒智信参与某文旅集团半年经营分析会》

近日,华恒智信项目组应邀参加某大型国企集团半年经营分析会。集团领导班子、各子公司负责人及主要部门负责人出席会议。本次会议旨在对集团上半年经营情况进行系统回顾,并为下半年各项工作的高效推进凝聚共识。会上,各子公司分别汇报了上半年…

阅读更多 →
《华恒智信向某文旅集团汇报管理诊断成果》 2026/9/3 13:18:52

《华恒智信向某文旅集团汇报管理诊断成果》

2026年7月中旬,华恒智信项目组就该集团人力资源管理咨询项目的阶段性诊断成果,向客户方领导班子进行了专题汇报。集团董事长、总经理及主要领导班子成员出席汇报会。汇报会上,华恒智信项目组老师基于前期全面调研所掌握的一手数据&#xff0c…

阅读更多 →
《华恒智信助力某文旅集团重构景区人力资源配置模式》 2026/9/3 13:18:52

《华恒智信助力某文旅集团重构景区人力资源配置模式》

近日,华恒智信项目组顺利完成某文旅集团景区板块人力资源配置优化方案的阶段性交付工作。本次项目聚焦旅游景区季节性用工难题,提出了以“客流工时联动”为核心的弹性编制方案,为景区实现降本增效、提升服务品质提供了系统的管理工具与方法支…

阅读更多 →
高德车机版湖山背景开关定位与问题排查指南 2026/9/3 13:18:52

高德车机版湖山背景开关定位与问题排查指南

在车机导航的使用体验里,“背景好不好看”看似只是锦上添花,实际上直接影响第一眼观感。最近不少车友在交流群里问同一个问题:高德地图车机版里的“湖山背景”到底怎么开?设置界面里明明看到相关关键词,却找不到一个明…

阅读更多 →
CS32L010 SDK深度解析:国产MCU嵌入式开发实战指南 2026/9/3 13:18:52

CS32L010 SDK深度解析:国产MCU嵌入式开发实战指南

简介:本资源是面向嵌入式开发者与国产MCU初学者的CS32L010芯片全栈开发支持包,聚焦低功耗音频与IoT终端应用开发场景,解决国产芯片入门难、文档分散、SDK集成不畅等实际问题。压缩包共2000个文件,大小24.99MB,涵盖C/H源…

阅读更多 →
GPS/INS松耦合组合导航原理与工程实践 2026/9/3 13:15:52

GPS/INS松耦合组合导航原理与工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞