C#和java对URL编码(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 
}
GarsonZhang www.yesdotnet.com

 

版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
YES开发框架
上一篇:微信支付:签名计算.net4.5
下一篇:C# RSA加密(私钥加密、公钥解密、密钥格式转换、支持超大长度分段加密)
评论列表

发表评论

评论内容
昵称:
关联文章

C#javaURL编码(UrlEncode)差异
C#中URL编码
JavascriptURL进行编码解码三种方式介绍
C#进化——C#发展史、C#1.0-10.0语法系统性梳理、C#与JAVA对比
C#未来一点感悟
C#代码编码规范手册 软件开发规范 开发指南
ASP.NET MVC使用@Url.Action 多个参数中间&被URL编码
C# 利用 SharpZipLib 多个文本字符串进行多文件打包为RAR或ZIP并进行下载
C#使用默认浏览器打开URL
ASP.NET MVCASP.NET Core MVC中获取当前URL/Controller/Action
JAVA JDK官方下载地址
算法:计算两个大量数据数组交集,差集,并集,(数据差异
微信授权连接URL生成类库
【gitblit复制URL】 修改URL复制方式Flash插件被浏览器禁用解决办法
附录:ASCII、UTF8、Uncicode 编码中英文字符大小
获取URL参数几种方式
TinyMCE 代码高亮 Prism.js C# language-csharp 没做处理
Python百度检索获得真实URL连接
C# 利用SharpZipLib*.rar压缩文件解压报错
C#数据类型常见数据库(SQLServer,MySQL,Oracle,SQLite)数据类型对应关系

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码