C#在与java对接时候的UrlEncode的坑
最近与建行接口做对接和与一家短信运营商做对接时候遇到了这个坑
在java中对UrlEncode 时候哪些url非安全字符被转为%数字和大写字幕组合,比如:zhangsan/d 会被转为 zhangsan%2Fd ,而在C#中确被转为 zhangsan%2fd 。注意大小写的差异
然后就导致了各种加密验签无法通过的情况。
于是就自己在C#原来的UrlEncode的基础上写了一个UrlEncode方法
/// <summary> /// Url编码 /// </summary> /// <param name="str">原字符串</param> /// <param name="encoding">编码格式</param> /// <param name="upper">特殊字符编码为大写</param> /// <returns></returns> static string UrlEncode(string str, Encoding encoding) { if (encoding == null) { encoding = UTF8Encoding.UTF8; } byte[] bytes = encoding.GetBytes(str); int num = 0; int num2 = 0; for (int i = 0; i < bytes.Length; i++) { char ch = (char)bytes[i]; if (ch == ' ') { num++; } else if (!IsUrlSafeChar(ch)) { num2++; //非url安全字符 } } if (num == 0 && num2 == 0) { return str; //不包含空格和特殊字符 } byte[] buffer = new byte[bytes.Length + (num2 * 2)]; //包含特殊字符,每个特殊字符转为3个字符,所以长度+2x int num3 = 0; for (int j = 0; j < bytes.Length; j++) { byte num6 = bytes[j]; char ch2 = (char)num6; if (IsUrlSafeChar(ch2)) { buffer[num3++] = num6; } else if (ch2 == ' ') { buffer[num3++] = 0x2B; //0x2B代表 ascii码中的+,url编码时候会把空格编写为+ } else { //特殊符号转换 buffer[num3++] = 0x25; //代表 % buffer[num3++] = (byte)IntToHex((num6 >> 4) & 15); //8位向右移动四位后 与 1111按位与 ,即保留高前四位 ,比如 /为 2f,则结果保留了2 buffer[num3++] = (byte)IntToHex(num6 & 15); //8位 ,与00001111按位与,即保留 后四位 ,比如 /为2f,则结果保留了 f } } return encoding.GetString(buffer); } static bool IsUrlSafeChar(char ch) { if ((((ch < 'a') || (ch > 'z')) && ((ch < 'A') || (ch > 'Z'))) && ((ch < '0') || (ch > '9'))) { switch (ch) { case '(': case ')': case '*': case '-': case '.': case '!': break; //安全字符 case '+': case ',': return false; //非安全字符 default: //非安全字符 if (ch != '_') { return false; } break; } } return true; } static char IntToHex(int n) //n为0-f { if (n <= 9) { return (char)(n + 0x30); //0x30 十进制是48 对应ASCII码是0 } return (char)((n - 10) + 0x41); //0x41 十进制是 65 对应ASCII码是A }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构