C# 参数签名字符串按 ASCII码排序,注意其中的坑
参数签名中通常是按键值对中键名称的ASCII按从小到大的顺序排序后进行hash为签名字符串。不要直接使用 SortedDictionary<string, string> 有坑的,他是按数字、小写字母、大写字母的顺序排的,实际规则应该是数字、大写字母、小写字母的顺序来排才对。一直使用他在支付宝和微信的接口中都没问题,因为支付宝和微信的单词是用下划线分隔的,今天接入的一家支付公司用的驼峰命名法坑就出现了。正确的打开姿势如下:
/// <summary>
/// ASCII值排序
/// </summary>
public class OrdinalComparer : System.Collections.Generic.IComparer<String>
{
public int Compare(String x, String y)
{
return string.CompareOrdinal(x, y);
}
}
//使用
//SortedDictionary<string, string> sDic 待排序的键值对
var sArr = sDic.OrderBy(x => x.Key, new OrdinalComparer()).ToDictionary(x => x.Key, y => y.Value);
//然后 foreach sArr 就OK了 //或者转为数组再排序
string[] arr = new string[sDic.Count];
Array.Sort(arr, string.CompareOrdinal); //ASCII排序
在和银行做数据对接时,涉及到数据传输时的验签及加密。其中数据签名方案中就要求数据项根据属性名按 ASCII码 进行升序排序。C#中的ASCII码排序并不是表面上那么简单,一不小心就入坑了。因为C#的排序默认并不是按照ASCII码进行排序的。举个例子, 我有这样一个字符串数组,然后对其排序。
string[] vv = { "", "", "A", "a", "B", "b" };
Array.Sort(vv); //结果 1 2 a A b B
如果是按照ASCII码进行排序的话,顺序应该是: 1, 2, A, B, a, b 而实际排序后的结果则是:1, 2, a, A, b, B . 这也就是说Sort()方法默认情况下并不是按ASCII码进行排序的。之后我也同样测试了C#中的OrderBy()的排序,发现它默认情况下也并不是按照ASCII码进行的排序。
string[] vv = { "", "", "A", "a", "B", "b" };
vv.OrderBy(x => x); //结果 1 2 a A b B
那么既然默认排序不是按ASCII码进行的排序,我们要怎么做呢? 看下面代码,只需要在原来排序方法上再加个参数: string.CompareOrdinal。string.CompareOrdinal会把每个字符先转成相应的数值(如 a 转为数值 97),然后再对数值进行比较。
Array.Sort(vv, string.CompareOrdinal); //ASCII排序
注:掉入这个坑是因为起初不知道如何对字符做ASCII码排序,于是百度了一把。得到的结果就是这个 C# 参数按照ASCII码从小到大排序(字典序) 而当我采用这种方式时,银行验签那步始终通不过,调试发现我排序后的结果和银行那边的不同。这篇博文的博主可能自己也没发现这个坑吧。
整理来源:
http://www.cnblogs.com/similar/p/6739293.html
http://www.cnblogs.com/similar/p/6739293.html
C# 参数签名字符串按 ASCII码排序,注意其中的坑的更多相关文章
- C# 字符串按 ASCII码 排序,注意其中的小坑
https://www.cnblogs.com/similar/p/6739293.html 在和银行做数据对接时,涉及到数据传输时的验签及加密.其中数据签名方案中就要求数据项根据属性名按 ASCII ...
- 字符串ASCII码排序
在对接第三方支付渠道的时候,第三方会要求参数按照ASCII码从小到大排序. 如下是渠道方有关生成签名规则的java代码示例: //初始化0010merkey.private文件: String mer ...
- ASCII码排序
ASCII码排序 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符. 输入 第一行输 ...
- ASCII码排序 南阳acm4
ASCII码排序 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符. 输入 第一行输 ...
- NYOJ4——ASCII码排序
ASCII码排序 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述:输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符. 输入:第一行输入一 ...
- [PHP] chr和ord函数实现字符串和ASCII码互转
chr和ord函数是用来字符串和ASCII码互转的. ASCII码是计算机所能显示字符的编码,它的取值范围是0-255,其中包括标点.字母.数字.汉字等.在编程过程中,经常把指定的字符转化为ASCI ...
- 杭电2000——ASCII码排序
/* ASCII码排序 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- 2000 ASCII码排序
声明:从今天开始每周至少做七道杭电ACM题,锻炼思考能力. 2000 ASCII码排序 Problem Description 输入三个字符后,按各字符的ASCII码从小到大的顺序输出这三个字符. ...
- 【hdu2000】ASCII码排序
题目来源:www.acm.hdu.edu.cn 题目编号:2000 ASCII码排序 /*----------------------------------------原题目------------ ...
随机推荐
- Word技巧【转载】
Word谁都会用,高手和菜鸟最明显的区别就是效率,有人可以轻车熟路一小时做完好几份Word,有人加班到深夜手酸脖子疼还没做好一份,不管用什么办公软件,效率都是第一追求.先看第一点: ❶如何快速选中 ...
- 深度学习目标检测:RCNN,Fast,Faster,YOLO,SSD比较
转载出处:http://blog.csdn.net/ikerpeng/article/details/54316814 知乎的图可以放大,更清晰,链接:https://www.zhihu.com/qu ...
- mysql复习
1.数据库操作 CREATE DATABASE 数据库名 charset utf8; 查看数据库 show databases; show create database db1; select da ...
- 原生js实现清除子元素节点
var table = document.body.querySelector('.mui-table-view'); while(table.hasChildNodes()) //当table下还存 ...
- python系统编程(七)
多线程-共享全局变量 from threading import Thread import time g_num = 100 def work1(): global g_num for i in r ...
- Java中的RASP实现
RSAP RASP是Gartner公司提出的一个概念,称:程序不应该依赖于外部组件进行运行时保护,而应该自身拥有运行时环境保护机制: RASP就是运行时应用自我保护(Runtime applicati ...
- Node_初步了解(1)
(1)在cmd或是git上面运行node.js文件,ctrl+c可以停掉之前的服务. (2)node.js本质是一个JavaScript运行环境. (3)node.js与浏览器控制台js执行环境的不同 ...
- [Java代码] Java用pinyin4j根据汉语获取各种格式和需求的拼音
pinyin4j是一个功能强悍的汉语拼音工具包,主要是从汉语获取各种格式和需求的拼音,功能强悍,下面看看如何使用pinyin4j.下面介绍用pinyin4j来做的一个根据汉语获取各种格式和需求的拼音d ...
- Node + Selenium使用小结
可参考网上的步骤进行操作.例如这篇文章:https://wangheng3751.github.io/2018/01/17/selenium/ 1.安装Node.js,去官网下载最新版本的Node.j ...
- one-stage object detectors(1)
2019/04/08 强烈推荐:深入理解one-stage目标检测算法 yolo系列 one-stage object detectors(YOLO and SSD) 在不专一的模型中,每个检测器应该 ...