电商项目之有趣的支付签名算法

文章目录
- 1 问题背景
- 2 思路
- 3 代码实现
1 问题背景
在发起支付的时候,一般都需要对发送的请求参数进行加密或者签名,下文简称这个过程为“签名”。行业内比较普遍的签发算法有:
(1)按支付渠道给定的字段排序进行拼接,最后再拼一个密钥,形成一个待签名的字符串tobeSign,然后对这个tobeSign进行MD5编码。比如MD5(商户号+子应用ID+商户订单号+流水号+金额+币种+密钥);
(2)针对请求参数中的字段(仅针对第一层的字段,不需要针对字段里面的字段,即不需要递归),进行字典升序排序,用格式key=value和&连接符拼接,最后再拼一个密钥,再用MD5编码比如MD5(a=value1&b=value2&key=密钥);
这次遇到一种比较有趣的签名算法,笔者认为是基于第(2)的变种,渠道方要求针对请求参数中的字段,如果该字段是对象类型,那么该字段里面的字段也要按字典升序排序进行拼接,相当于是递归字典升序,困难度有一点提升
2 思路
文字描述得有点抽象,可以结合第3小节的代码实现来看
遍历每一层字段,都用一个容器存起来,要按字典升序存。维护一个层序遍历的容器——双向队列。将前面升序的数据入队。遍历队列的每一元素,元素从队头出队,再遍历元素中的字段是否是对象类型或者数组类型,使用一个容器存起来,要按字典降序存,存完后使用头插法入队。使用头插法倒叙入队,每一次从队头遍历,那么每一次遍历都是升序遍历。
3 代码实现
解释:代码中的
BeansUtil.bean2MapIgnoreEmptyStr()是将对象转成一个Map。SymbolConstant.EQUAL的值是一个=,SymbolConstant.AND的值是一个&
public static String buildToBeSignStr(Object payReq) {// 将对象转成一个MapMap<String, String> map = BeansUtil.bean2MapIgnoreEmptyStr(payReq);TreeMap<String, String> treeMap = new TreeMap<>(map);List<String> result = new LinkedList<>();for (Map.Entry<String, String> entry : treeMap.entrySet()) {// 层序遍历容器Deque<Map.Entry<String, String>> bfsHolder = new LinkedList<>();// 结果暂存容器List<String> tmpResult = new LinkedList<>();// 入队bfsHolder.offer(entry);while (CollectionUtils.isNotEmpty(bfsHolder)) {Map.Entry<String, String> pollEntry = bfsHolder.poll();String pKey = pollEntry.getKey();String pVal = pollEntry.getValue();if (StringUtils.isNotBlank(pVal) && JSONValidator.from(pVal).validate()) {// 是json串,仍需要继续解析log.info("value of key:{} is json str.", pKey);// 解析JSON字符串Object parsedObject = JSON.parse(pVal);boolean isJSONObject = parsedObject instanceof JSONObject;boolean isJSONArray = parsedObject instanceof JSONArray;if (isJSONObject || isJSONArray) {Map<String, String> map1 = null;if (isJSONObject) {log.info("JSON字符串是一个对象");JSONObject jsonObject = (JSONObject) parsedObject;// 处理对象map1 = BeansUtil.buildMapFromJsonStr(pVal);} else if (isJSONArray) {System.out.println("JSON字符串是一个数组");JSONArray jsonArray = (JSONArray) parsedObject;// 处理数组for (Object o : jsonArray) {map1 = BeansUtil.bean2MapIgnoreEmptyStr(o);}}if (MapUtils.isNotEmpty(map1)) {// 倒叙排序Map<String, String> treeMap1 = new TreeMap<>(Comparator.reverseOrder());treeMap1.putAll(map1);// 插入到队头Streams.of(treeMap1.entrySet()).forEach(bfsHolder::offerFirst);}} else {tmpResult.add(pKey + SymbolConstant.EQUAL + pVal);}} else {tmpResult.add(pKey + SymbolConstant.EQUAL + pVal);}}if (CollectionUtils.isNotEmpty(tmpResult)) {String tmpResultStr = String.join(SymbolConstant.AND, tmpResult);result.add(tmpResultStr);}}if (CollectionUtils.isNotEmpty(result)) {return String.join(SymbolConstant.AND, result);}return "";}
相关文章:
电商项目之有趣的支付签名算法
文章目录 1 问题背景2 思路3 代码实现 1 问题背景 在发起支付的时候,一般都需要对发送的请求参数进行加密或者签名,下文简称这个过程为“签名”。行业内比较普遍的签发算法有: (1)按支付渠道给定的字段排序进行拼接&am…...
Web开发核心
文章目录 1.http协议简介2.http协议特性3.http请求和响应协议4.最简单的Web程序5.基于flask搭建web⽹站6.浏览器开发者⼯具(重点) 1.http协议简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于 万维网(WWW:Norld W…...
【Python】【Scrapy 爬虫】理解HTML和XPath
为了从网页中抽取信息,必须对其结构有更多了解。我们快速浏览HTML、HTML的树状表示,以及在网页上选取信息的一种方式XPath。 HTML、DOM树表示以及XPath 互联网是如何工作的? 当两台电脑需要通信的时候,你必须要连接他们ÿ…...
【CTF Web】CTFShow web5 Writeup(SQL注入+PHP+位运算)
web5 1 阿呆被老板狂骂一通,决定改掉自己大意的毛病,痛下杀手,修补漏洞。 解法 注意到: <!-- flag in id 1000 -->拦截很多种字符,连 select 也不给用了。 if(preg_match("/\|\"|or|\||\-|\\\|\/|\…...
LeetCode 968.监控二叉树 (hard)
968.监控二叉树 力扣题目链接(opens new window) 给定一个二叉树,我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。 计算监控树的所有节点所需的最小摄像头数量。 贪心思路: 从下往上看,局部最…...
数理逻辑:1、预备知识
17.1 命题和联结词 命题:可以判定真假的陈述句。(则悖论,祈使句,疑问句都不是命题) 原子命题:不能被分割为更小的命题的命题 例如: 2既是素数又是偶数 可以由$p: 2 是素数,…...
14-云原生监控体系-Redis_exporter 监控 MySQL[部署Dashborad告警规则实战]
文章目录 环境准备切片集群主从哨兵1. 部署1.1. 二进制方式1.1.1. 下载二进制包1.1.2. 部署1.2. docker-compose 容器方式1.3. 配置连接&认证参数1.3.1. 连接认证参数1.3.2. 配置服务控制 systemd2. 配置到 Prometheus3 Dashboard4. 告警规则...
DOS学习-目录与文件应用操作经典案例-xcopy
新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一.前言 二.使用 三.案例 一.前言 xcopy命令是DOS系统中一个强大的文件和目录复制工具&…...
Midjourney是一个基于GPT-3.5系列接口开发的免费AI机器人
Midjourney是一个基于GPT-3.5系列接口开发的免费AI机器人,旨在提供多领域的智能对话服务。Midjourney在不同领域中有不同的定义和应用,以下是对其中两个主要领域的介绍: Midjourney官网:https://www.midjourney.com/ 一、AI绘画工…...
v-model详解
目录 原理 作用 表单类组件封装 编辑v-model简化代码 原理 v-model本质上是一个语法糖。例如应用在输入框上,就是value属性和input属性的合写。 作用 提供数据的双向绑定。 数据变,视图跟着变:value视图变,数据跟着变input 注意&…...
ArcGIS中分割与按属性分割的区别
1、分割ArcGIS批量导出各个市的县级行政边界 视频教学: ArcGIS批量导出各个市的县级行政边界002 2、ArcGIS批量导出全国各省的边界 视频教学: ArcGIS导出全国各省的边界003 推荐学习: ArcGIS全系列实战视频教程——9个单一课程组合系列直播回…...
就业班 第三阶段(ELK) 2401--5.20 day1 ELK 企业实战 ES+head+kibana+logstash部署(最大集群)
ELKkafkafilebeat企业内部日志分析系统 1、组件介绍 1、Elasticsearch: 是一个基于Lucene的搜索服务器。提供搜集、分析、存储数据三大功能。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的ÿ…...
PCM和QAM
PCM(脉冲编码调制)和QAM(正交振幅调制)是两种不同的信号调制技术,它们在通信系统中有着不同的应用和特点。 PCM(脉冲编码调制) 概述 PCM是一种数字信号处理技术,用于将模拟信号转…...
Mongodb分布式id
1、分布式id使用场景 分布式ID是指在分布式系统中用于唯一标识每个元素的数字或字符串。在分布式系统中,各个节点或服务可能独立运行在不同的服务器、数据中心或地理位置,因此需要一种机制来确保每个生成的ID都是全局唯一的,以避免ID冲突。 …...
AI模型抉择:开源VS闭源,谁主沉浮?
AI模型抉择:开源VS闭源,谁主沉浮? 😄生命不息,写作不止 🔥 继续踏上学习之路,学之分享笔记 👊 总有一天我也能像各位大佬一样 🏆 博客首页 怒放吧德德 To记录领地 &am…...
佩戴安全头盔监测识别摄像机
佩戴安全头盔是重要的安全措施,尤其在工地、建筑工程和工业生产等领域,安全头盔的佩戴对于工人的生命安全至关重要。为了更好地管理和监控佩戴安全头盔的情况,监测识别摄像机成为了一项重要的工具。监测识别摄像机可以通过智能技术监测并记录…...
5.24学习记录
[FSCTF 2023]ez_php2 比较简单的pop链 <?php highlight_file(__file__); Class Rd{public $ending;public $cl;public $poc;public function __destruct(){echo "All matters have concluded";die($this->ending);}public function __call($name, $arg){for…...
创建FreeRTOS工程
创建STM32CubeMX工程 配置时钟 配置FreeRTOS 生成Keil MDK的工程 打开工程 结尾 这就是我们用STM32CubeMX创建的最基本的一个FreeRTOS的工程。可以看到,这个与我们使用stm32开发的裸机程序有相同的地方,也有不同的地方,我们可以发现&am…...
HTML中 video标签样式铺满全屏
video标签默认不是铺满的,即使手动设置宽高100%也不会生效,所以当需要video铺满div时,需要加上一个css样式 <videocontrolsstyle"width: 100%; height: 100%; object-fit: fill"autoplay:src"item.video" ></v…...
vue项目移动端商场
一、项目前端页面展示 二、项目整体目录结构 三、项目流程 1. vue快速创建基础项目 创建项目 vue create hk-shop 1 选择需要的配置 创建基础文件夹目录 src文件夹下文件夹目录: ① views 文件夹存放界面 ② components 文件夹存放界面中局部组件 ③ config 文件夹存…...
Buzz音频转录完全指南:3大核心功能+5个实战场景,快速掌握本地语音转文字技术
Buzz音频转录完全指南:3大核心功能5个实战场景,快速掌握本地语音转文字技术 【免费下载链接】buzz Buzz transcribes and translates audio offline on your personal computer. Powered by OpenAIs Whisper. 项目地址: https://gitcode.com/GitHub_Tr…...
Taotoken的TokenPlan套餐如何实现更经济的模型调用
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Taotoken的TokenPlan套餐如何实现更经济的模型调用 1. 理解TokenPlan的计费模式 在模型应用开发过程中,成本的可预测性…...
第3篇:系统透视——信息部门如何构建“税务友好型”IT架构
本篇导读:如果你是信息总监或IT负责人,请通读全文,尤其是“系统合规设计的三必须”和“现场检查SOP”;如果你是财税人员,请重点阅读“研产供销全链条的系统对接要求”和“与IT部门的协作要点”;如果你是老板…...
组态王通用扫码枪配置
使用组态王扫码枪驱动,是绑定变量,扫码后直接就可以显示扫码内容。解决每次扫码输入数据时必须先用鼠标点进输入框内的问题。驱动安装先添加驱动,亚控网站的文件为 barcodescanner,这个文件是组态王通用扫码枪的驱动,但…...
DeepSeek-R1补全能力封测倒计时(仅剩72小时开放API灰度权限):这份内部测试SOP已被3家头部科技公司紧急采购
更多请点击: https://intelliparadigm.com 第一章:DeepSeek-R1代码补全能力封测全景概览 DeepSeek-R1 是深度求索(DeepSeek)推出的高性能开源推理模型,在代码补全场景中展现出显著的上下文理解力与多语言泛化能力。本…...
【深度解析】AI Coding 模型竞速:从 Claude Mythos 安全编码到 GPT-5.6 传闻,如何落地代码审查智能体
摘要 AI 编码模型正在从“代码补全”进入“复杂代码库理解、漏洞发现与自动修复”阶段。本文结合 Claude Mythos、Claude Opus 4.8 与 GPT-5.6 相关信息,解析新一代 Coding Agent 的技术趋势,并给出基于大模型 API 的代码安全审查实战方案。背景介绍&…...
随机森林算法在儿童出行方式预测中的实战应用与优化
1. 项目概述:用随机森林预测孩子怎么上学做城市交通规划或者做家长接送方案的时候,你肯定想过一个问题:孩子们到底是怎么上学的?是走路、骑车、坐公交还是家长开车送?这个问题看似简单,背后却牵扯到城市规划…...
Unity Visual Scripting不是拖拽玩具:中阶开发者的编程范式重构指南
1. 为什么Unity官方Visual Scripting不是“拖拽完就能跑”的玩具,而是一套需要重新理解的编程范式很多人第一次点开Unity的Visual Scripting(VS)面板时,看到那些五颜六色的节点和丝滑的连线,下意识觉得:“这…...
巨量投放总结
巨量商务管理平台 : https://business.oceanengine.com 巨量广告投放平台: https://ad.oceanengine.com 商务管理平台 账户 广告组 计划 广告投放平台 层级关系: 广告组 -> 计划 -> 创意 对应FB: 系列 - > 广告组 -> 广告...
终极指南:5步快速掌握免费的3D点云标注工具labelCloud
终极指南:5步快速掌握免费的3D点云标注工具labelCloud 【免费下载链接】labelCloud A lightweight tool for labeling 3D bounding boxes in point clouds. 项目地址: https://gitcode.com/gh_mirrors/la/labelCloud 想要为自动驾驶、机器人视觉或3D目标检测…...
