首页 > 代码库 > c#: UrlDecode()

c#: UrlDecode()

1、源起:

KV需要解析从插件传来的URL网址,因为其可能经过编码,所以需要解码。

初用System.Web.HttpUtility.UrlDecode()这个函数,但根据用户环境crash场景,发现有.net framework库不全情况,即找不到System.Web.dll这个程序集。

居然有此等事情!

自写代码解析喽,在网上下载得System.Web源代码,抽离所需函数,满足需求,项目可以舍弃对System.Web的引用

 

2、UrlDecode(string str)

直贴代码以做备忘:

        public static string UrlDecode(string str)
        {
            return UrlDecode(str, Encoding.UTF8);
        }

        static void WriteCharBytes(IList buf, char ch, Encoding e)
        {
            if (ch > 255)
            {
                foreach (byte b in e.GetBytes(new char[] { ch }))
                    buf.Add(b);
            }
            else
                buf.Add((byte)ch);
        }

        static int GetInt(byte b)
        {
            char c = (char)b;
            if (c >= 0 && c <= 9)
                return c - 0;

            if (c >= a && c <= f)
                return c - a + 10;

            if (c >= A && c <= F)
                return c - A + 10;

            return -1;
        }

        static int GetChar(string str, int offset, int length)
        {
            int val = 0;
            int end = length + offset;
            for (int i = offset; i < end; i++)
            {
                char c = str[i];
                if (c > 127)
                    return -1;

                int current = GetInt((byte)c);
                if (current == -1)
                    return -1;
                val = (val << 4) + current;
            }

            return val;
        }

        static string UrlDecode(string s, Encoding e)
        {
            if (null == s)
                return null;

            if (s.IndexOf(%) == -1 && s.IndexOf(+) == -1)
                return s;

            if (e == null)
                e = Encoding.UTF8;

            long len = s.Length;
            var bytes = new List<byte>();
            int xchar;
            char ch;

            for (int i = 0; i < len; i++)
                ch = s[i];
                if (ch == % && i + 2 < len && s[i + 1] != %)
                {
                    if (s[i + 1] == u && i + 5 < len)
                    {
                        // unicode hex sequence
                        xchar = GetChar(s, i + 2, 4);
                        if (xchar != -1)
                        {
                            WriteCharBytes(bytes, (char)xchar, e);
                            i += 5;
                        }
                        else
                            WriteCharBytes(bytes, %, e);
                    }
                    else if ((xchar = GetChar(s, i + 1, 2)) != -1)
                    {
                        WriteCharBytes(bytes, (char)xchar, e);
                        i += 2;
                    }
                    else
                    {
                        WriteCharBytes(bytes, %, e);
                    }
                    continue;
                }

                if (ch == +)
                    WriteCharBytes(bytes,  , e);
                else
                    WriteCharBytes(bytes, ch, e);
            }

            byte[] buf = bytes.ToArray();
            bytes = null;
            return e.GetString(buf);
        }

 

 3、简单验证

    string url = "https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DLeghS9MH9xY";
    url = UrlDecode(url);
    Console.WriteLine(url);  //url = https://www.youtube.com/watch?v=LeghS9MH9xY

c#: UrlDecode()