Base64编解码中的坑

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Base64编解码中的坑相关的知识,希望对你有一定的参考价值。

本文主要针对.net 中的System.Web.ServerUtility.UrlTokenEncode()/UrlTokenDecode()进行解释

在巨硬的源码文档中找到4.6.2的释义:

https://referencesource.microsoft.com/#System.Web/Util/HttpEncoder.cs,0e3cb83cf51ca334

 

通过分析可知

1:最后一个‘=‘被编码成一个由源字符串与其长度差的加密字符.

2:‘+‘ to ‘-‘,‘/‘ to ‘_‘

相信看到这里读者都已经发现问题所在了,如果在不知道源字符串长度与最后一个补位符存在与否的情况下想解码获得源字符串是不大可能的。

那怎么办呢?自己手动写一个呗...

编码:

        /// <summary>
        /// 字节码转为base64
        /// 替换System.Web.ServerUtility.UrlTokenEncode方法
        ///  "/" to "_a","+" to "_b", and "=" to "_c"
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        internal static string UrlTokenEncode(byte[] input)
        {
            if (input == null)
                throw new ArgumentNullException("input");
            if (input.Length < 1)
                return String.Empty;

            string base64Str = null;
            StringBuilder newbase64Str = new StringBuilder();
            ////////////////////////////////////////////////////////
            // Step 1: Do a Base64 encoding
            base64Str = Convert.ToBase64String(input);

            ////////////////////////////////////////////////////////
            // Step 2: Copy in the other chars. Transform the "/" to "_a" ,"+" to "_b", and "=" to "_c"
            foreach(var i in base64Str)
            {
                switch (i)
                {
                    case ‘/‘:
                        newbase64Str.Append( "_a");
                        break;
                    case ‘+‘:
                        newbase64Str.Append( "_b");
                        break;
                    case ‘=‘:
                        newbase64Str.Append( "_c");
                        break;

                    default:
                        newbase64Str.Append(i);
                        break;
                }
            }
            return newbase64Str.ToString();
        }

解码:

        /// <summary>
        /// base64解码
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        internal static byte[] UrlTokenDecode(string input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            string newInput = input.Replace("_a", "/").Replace("_b", "+").Replace("_c", "=");
            int len = newInput.Length;
            if (len < 1)
                return new byte[0];

            // Do the actual conversion
            return Convert.FromBase64String(newInput);
        }

不要问我为什么不把核心的编解码代码自己实现,因为懒。ok?

以上是关于Base64编解码中的坑的主要内容,如果未能解决你的问题,请参考以下文章

Lua Base64自定义编解码

Lua Base64自定义编解码

Lua Base64自定义编解码

VC++详解Base64编解码原理以及Base64编解码接口实现(附源码)

base64编码与解码

python3的base64编解码