16

I have been looking how to validate a base64 string and came across this.

 ^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$

I need a little help to make it allow "==" aswell as "=".

Thanks

3
  • What do you mean? == and = are already allowed. Commented Jul 28, 2010 at 17:08
  • Yes your right it works. Sorry it was me just adding a extra "=" on my encoded string to test when I needed to make a new encoded string that contains "==" :) Commented Jul 28, 2010 at 17:14
  • note that plus sign needs to be escaped. like this: ^(?:[A-Za-z0-9\+/]{4})*(?:[A-Za-z0-9\+/]{2}==|[A-Za-z0-9\+/]{3}=)?$ Commented Feb 4, 2018 at 23:53

2 Answers 2

22

This should perform extremely well.

private static readonly HashSet<char> _base64Characters = new HashSet<char>() { 
    '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', '+', '/', 
    '='
};

public static bool IsBase64String(string value)
{
    if (string.IsNullOrEmpty(value))
    {
        return false;
    }
    else if (value.Any(c => !_base64Characters.Contains(c)))
    {
        return false;
    }

    try
    {
        Convert.FromBase64String(value);
        return true;
    }
    catch (FormatException)
    {
        return false;
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I'd prefer the clarity of this version unless you expect a lot of invalid data.
Might as well use Base64 to check rather then RegEx...makes sense ;)
This is NOT a valid solution, it doesn't count the number of padding characters or the total count of characters
The first if .. else always fail in my test; however your try/catch always work, but I think this is expensive in the long run.
8

I've updated the above code a bit to meet few more requirements:

  • check for correct string size (should be multiple of 4)
  • check for pad character count (should be up to 2 character at the end of the string only)
  • make it work in .NET 2.0 (well, the HashSet<T> should be implemented or use Dictionary<T, U>)

The code is a part of my assertion library, so this is why there are two check methods and the param parameter...

    private const char Base64Padding = '=';

    private static readonly HashSet<char> Base64Characters = new HashSet<char>()
    { 
        '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', '+', '/'
    };

    public static void CheckBase64String(string param, string paramName)
    {
        if (CheckBase64StringSafe(param) == false)
        {
            throw (new ArgumentException(String.Format("Parameter '{0}' is not a valid Base64 string.", paramName)));
        }
    }

    public static bool CheckBase64StringSafe(string param)
    {
        if (param == null)
        {
            // null string is not Base64 something
            return false;
        }

        // replace optional CR and LF characters
        param = param.Replace("\r", String.Empty).Replace("\n", String.Empty);

        if (param.Length == 0 ||
            (param.Length % 4) != 0)
        {
            // Base64 string should not be empty
            // Base64 string length should be multiple of 4
            return false;
        }

        // replace pad chacters
        int lengthNoPadding = param.Length;
        int lengthPadding;

        param = param.TrimEnd(Base64Padding);
        lengthPadding = param.Length;

        if ((lengthNoPadding - lengthPadding) > 2)
        {
            // there should be no more than 2 pad characters
            return false;
        }

        foreach (char c in param)
        {
            if (Base64Characters.Contains(c) == false)
            {
                // string contains non-Base64 character
                return false;
            }
        }

        // nothing invalid found
        return true;
    }

I've not tested the code extensively, so there no functionality guarantees at all!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.