Код для декодирования/кодирования измененного URL-адреса base64

Я хочу, чтобы base64 закодировал данные, чтобы поместить их в URL-адрес, а затем декодировать его в моем HttpHandler.

Я обнаружил, что Base64 Encoding позволяет использовать символ '/', который испортит совпадение UriTemplate. Затем я обнаружил, что существует концепция "модифицированного Base64 для URL" из википедии:

Существует модифицированный вариант Base64 для URL, в котором не будет использоваться padding '=', а символы '+' и '/' стандартного Base64 заменяются соответственно на "-" и "_", поэтому использование URL-адреса кодеры/декодеры больше не нужны и не влияют на длину закодированного значения, оставляя неизменную такую ​​же закодированную форму для использования в реляционных базах данных, веб-формах и идентификаторах объектов вообще.

Использование .NET. Я хочу изменить свой текущий код, выполнив базовую кодировку и декодирование base64, используя метод "измененный base64 для URL". Кто-нибудь сделал это?

Чтобы декодировать, я знаю, что он начинается с чего-то вроде:

string base64EncodedText = base64UrlEncodedText.Replace('-', '+').Replace('_', '/');

// Append '=' char(s) if necessary - how best to do this?

// My normal base64 decoding now uses encodedText

Но мне нужно добавить один или два символа '=' в конец, который выглядит немного сложнее.

Моя логика кодирования должна быть немного проще:

// Perform normal base64 encoding
byte[] encodedBytes = Encoding.UTF8.GetBytes(unencodedText);
string base64EncodedText = Convert.ToBase64String(encodedBytes);

// Apply URL variant
string base64UrlEncodedText = base64EncodedText.Replace("=", String.Empty).Replace('+', '-').Replace('/', '_');

Я видел Guid для Base64 для URL запись StackOverflow, но имеет известную длину, и поэтому они могут жестко кодировать количество равных знаков, необходимых в конце.

Ответ 1

Это следует правильно исправить: -

 base64 = base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '=');

Ответ 2

Также проверьте класс HttpServerUtility с помощью методов UrlTokenEncode и UrlTokenDecode, которые обрабатывают безопасное кодирование и декодирование Base64.

Примечание 1: Результат не является допустимой строкой Base64. Некоторые небезопасные символы для URL-адреса заменяются.

Примечание 2: Результат отличается от алгоритма base64url в RFC4648.

///<summary>
/// Base 64 Encoding with URL and Filename Safe Alphabet using UTF-8 character set.
///</summary>
///<param name="str">The origianl string</param>
///<returns>The Base64 encoded string</returns>
public static string Base64ForUrlEncode(string str)
{
    byte[] encbuff = Encoding.UTF8.GetBytes(str);
    return HttpServerUtility.UrlTokenEncode(encbuff);
}
///<summary>
/// Decode Base64 encoded string with URL and Filename Safe Alphabet using UTF-8.
///</summary>
///<param name="str">Base64 code</param>
///<returns>The decoded string.</returns>
public static string Base64ForUrlDecode(string str)
{
    byte[] decbuff = HttpServerUtility.UrlTokenDecode(str);
    return Encoding.UTF8.GetString(decbuff);
}

Ответ 3

Я попал сюда, ища код для кодирования/декодирования для кодировки base64url, который немного отличается от base64, как объясняется в вопросе.

Найден фрагмент кода С# в этом документе. JSON Web Signature ietf draft

Ответ 4

Недостаточно очков для комментариев, но в случае, если это помогает, фрагмент кода, который Sushil нашел в предоставленной ссылке (JSON Web Signature ietf draft), работает при кодировании Base 64 в качестве параметра в URL-адресе.

Скопированный фрагмент ниже для ленивых:

    static string Base64UrlEncode(byte[] arg)
    {
        string s = Convert.ToBase64String(arg); // Regular base64 encoder
        s = s.Split('=')[0]; // Remove any trailing '='s
        s = s.Replace('+', '-'); // 62nd char of encoding
        s = s.Replace('/', '_'); // 63rd char of encoding
        return s;
    }

    static byte[] Base64UrlDecode(string arg)
    {
        string s = arg;
        s = s.Replace('-', '+'); // 62nd char of encoding
        s = s.Replace('_', '/'); // 63rd char of encoding
        switch (s.Length % 4) // Pad with trailing '='s
        {
            case 0: break; // No pad chars in this case
            case 2: s += "=="; break; // Two pad chars
            case 3: s += "="; break; // One pad char
            default: throw new System.Exception(
              "Illegal base64url string!");
        }
        return Convert.FromBase64String(s); // Standard base64 decoder
    }

Ответ 5

По сравнению с принятым ответом, вот как вы в принципе декодируете кодированный base64 URL-адрес, используя С#:

Decode:

string codedValue = "base64encodedUrlHere";

string decoded;
byte[] buffer =  Convert.FromBase64String(codedValue);
decoded = Encoding.UTF8.GetString(buffer);