C # · pit draining · nonstandard Base64 conversion failed

Time:2021-10-23
Reading time |1.66 minutes word count |2664.8 characters
primary coverage |1. Introduction & background
“C # · pit drainage · nonstandard Base64 conversion failed”
Author | SCscHero Writing time | 2021/7/23 PM8:41
Article type |Series Degree of completion |Completed
motto Every great cause has a trivial beginning.

1、 Introduction & background    Completion: 100%


a) Dealing with problems

In C #Convert.FromBase64String()Method conversionSome nonstandard Base64 encoded strings with “=” or “= =” omitted tails, an error will be reported. The details are as follows:

System.FormatException
  HResult=0x80131537
  Invalid length of message = base-64 character array or string.
  Source=mscorlib
  StackTrace:
   In system.convert.frombase64_ Decode(Char* startInputPtr, Int32 inputLength, Byte* startDestPtr, Int32 destLength)
   In system.convert.frombase64charptr (char * inputptr, int32 inputlength)
   In system.convert.frombase64string (string s)
   In_ 00056._ Console_ FW4_ 7_ CSharp parses non-standard Base64 problems. Program. Main (string [] args) is in D: \ 00070. Code warehouse \ 00056_ Console_ FW4_ 7_ CSharp parsing non-standard Base64 problem \ program.cs: line 35

  This exception was originally thrown in this call stack: 
    System.Convert.FromBase64_Decode(char*, int, byte*, int)
    System.Convert.FromBase64CharPtr(char*, int)
    System.Convert.FromBase64String(string)
    _ 00056._ Console_ FW4_ 7_ CSharp resolves non-standard Base64 problems. Program. Main (string []) (in program. CS)

In some languages, such as Java, the native method supports this non-standard Base64 string parsing. However, in c#, if the native method of convert. Frombase64string () is used, the base64 standard is strictly reviewed. So we need to make some modifications to be compatible with this kind of non-standard string.

b) Response scenario

  1. It is applied to the c# technology stack to decode Base64 non-standard strings.
  2. In case of online Base64 parsing, the website can be parsed, but in c#Convert.FromBase64String()The method reports a scenario where the length of a base-64 character array or string is invalid.

c) Outline of this paper

  1. Principle analysis
    • Judgment basis of non-standard Base64 string
    • Generation scenario of non-standard Base64 string
  2. Method of c# parsing non-standard Base64
    • Replacement filling method
    • Compatible from generation principle
    • Use methods from third-party packages

2、 Verify the judgment basis of non-standard Base64 string    Completion: 100%


a) Judgment basis of non-standard Base64 string

The length of a valid Base64 encoded string should be separable by 4, and should be filled with 1 or 2 padding characters “=”. Padding is optional, but c# decodes the base64 encoded string strictly, so the missing padding symbol needs to be added. In addition, there are two Base64 specific characters “‘” and “-” that need to be replaced with “/” and “+”.

b) Generation scenario of non-standard Base64 string

If the blogger encounters a situation, the base64 encrypted string received by the blogger is generated by a java program. A parameter setting of java encryption method will lead to the generation of non-standard Base64 string.

3、 Method of c# parsing non-standard Base64    Completion: 100%


a) Scheme 1: replacement & filling method

According to the judgment basis of non-standard Base64 string, we can use the following alternative writing:

var tempStr = base64StrNoStand.Replace('_', '/').Replace('-', '+');
switch (base64StrNoStand.Length % 4)
{
    case 2: base64StrNoStand += "=="; break;
    case 3: base64StrNoStand += "="; break;
}
byte[] byteArray2 = Convert.FromBase64String(base64StrNoStand);
Console.WriteLine(Encoding.UTF8.GetString(byteArray2));

b) Scheme 2: compatible from generation principle

The principle is not studied in depth. At this stage, bloggers mainly do upper-level applications. The following is a public method for compatible implementation, and the code is as follows:

/// 
    ///Base64 decoding class
    ///Convert Base64 encoded string type to byte [] type
    /// 
    public class Base64Decoder
    {
        char[] source;
        int length, length2, length3;
        int blockCount;
        int paddingCount;
        public static Base64Decoder Decoder = new Base64Decoder();

        public Base64Decoder()
        {
        }

        private void init(char[] input)
        {
            int temp = 0;
            source = input;
            length = input.Length;

            for (int x = 0; x < 2; x++)
            {
                if (input[length - x - 1] == '=')
                    temp++;
            }

            paddingCount = temp;

            blockCount = length / 4;
            length2 = blockCount * 3;
        }

        public byte[] GetDecoded(string strInput)
        {
            //Initialization
            init(strInput.ToCharArray());

            byte[] buffer = new byte[length];
            byte[] buffer2 = new byte[length2];

            for (int x = 0; x < length; x++)
            {
                buffer[x] = char2sixbit(source[x]);
            }

            byte b, b1, b2, b3;
            byte temp1, temp2, temp3, temp4;

            for (int x = 0; x < blockCount; x++)
            {
                temp1 = buffer[x * 4];
                temp2 = buffer[x * 4 + 1];
                temp3 = buffer[x * 4 + 2];
                temp4 = buffer[x * 4 + 3];

                b = (byte) (temp1 << 2);
                b1 = (byte) ((temp2 & 48) >> 4);
                b1 += b;

                b = (byte) ((temp2 & 15) << 4);
                b2 = (byte) ((temp3 & 60) >> 2);
                b2 += b;

                b = (byte) ((temp3 & 3) << 6);
                b3 = temp4;
                b3 += b;

                buffer2[x * 3] = b1;
                buffer2[x * 3 + 1] = b2;
                buffer2[x * 3 + 2] = b3;
            }

            length3 = length2 - paddingCount;
            byte[] result = new byte[length3];

            for (int x = 0; x < length3; x++)
            {
                result[x] = buffer2[x];
            }

            return result;
        }

        private byte char2sixbit(char c)
        {
            char[] lookupTable = new char[64]
            {
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
                'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
                'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
            };
            if (c == '=')
                return 0;
            else
            {
                for (int x = 0; x < 64; x++)
                {
                    if (lookupTable[x] == c)
                        return (byte) x;
                }

                return 0;
            }
        }
    }

c) Use methods from third-party packages

For example, the method of decoding Base64 in the third-party package newtonsoft.json.

4、 Statements and references    Completion: 100%


Original blog post, please do not reprint without permission.

If you are helpful, you are welcome to like, collect and pay attention. If you have any questions, please comment! If you need to contact the blogger, you can write scschero directly.

Recommended Today

OC basis

IOS development interview essential skills chart.png What are objects and what are the objects in OC? An object is an instance of a class; Is an instance created through a class, which is generally called an instance object; Common objects in OC include instance objects, class objects, and metaclass objects; What is a class? What […]