Code pour décoder / encoder une URL base64 modifiée

je veux base64 Encoder des données pour les mettre dans une URL et les décoder dans mon HttpHandler.

j'ai trouvé que Base64 permet un caractère '/' qui va gâcher mon UriTemplate de correspondance. Puis j'ai trouvé qu'il y a un concept de "base 64 modifiée pour URL" de wikipedia:

il existe une version modifiée de Base64 pour la variante URL, où aucun padding '=' ne sera utilisé, et les caractères ' + ' et ' / ' de standard Base64 sont respectivement remplacés par " - "et"_", de sorte que l'utilisation D'encodeurs/décodeurs D'URL n'est plus nécessaire et n'a aucun impact sur la longueur de la valeur codée, laissant la même forme codée intacte pour une utilisation dans les bases de données relationnelles, les formulaires web, et les identificateurs d'objet en général.

en utilisant .NET je veux modifier mon code actuel de base64 en utilisant la méthode" modified base64 for URL". Quelqu'un a fait cela?

à decode, je sais que ça commence avec quelque chose comme:

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

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

// My normal base64 decoding now uses encodedText

mais, je dois potentiellement ajouter un ou deux ' = ' caractères à la fin qui semble un peu plus complexe.

ma logique d'encodage devrait être un peu plus simple:

// 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('/', '_');

j'ai vu le Guid Base64 Pour URL entrée StackOverflow, mais qui a une longueur connue et donc ils peuvent hardcode le nombre de signes égaux nécessaires à la fin.

103
demandé sur Community 2009-08-04 20:58:54

5 réponses

cela devrait le garnir correctement: -

 base64 = base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '=');
57
répondu AnthonyWJones 2009-08-04 21:36:49

aussi vérifier la classe HttpServerUtility avec UrlTokenEncode et UrlTokenDecode méthodes qui manipule URL safe Base64 encoding et décodage.

Note 1: le résultat n'est pas une chaîne de caractères base64 valide. Certains caractères dangereux pour URL sont remplacés.

Note 2: le résultat diffère de l'algorithme de base64url dans 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);
}
170
répondu Fredrik Haglund 2013-04-07 10:09:02

pas assez de points pour commenter, mais au cas où cela aiderait, le code snippet que Sushil a trouvé dans le lien fourni (JSON Web Signature IETF draft) fonctionne lorsque la Base 64 est encodée comme paramètre dans L'URL.

Copie ci-dessous pour ceux qui sont paresseux:

    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
    }
20
répondu Stefan Zvonar 2015-10-13 22:40:00

j'ai frappé ici en cherchant du code pour coder/décoder l'encodage de base64url qui est peu différent de base64 comme expliqué dans la question.

trouvé code C# snippet dans ce document. JSON Web de la Signature de l'ietf projet

18
répondu Sushil 2013-01-16 08:23:14

en comparaison à la réponse acceptée, voici comment vous feriez fondamentalement décoder une url encodée base64, en utilisant C#:

Décoder:

string codedValue = "base64encodedUrlHere";

string decoded;
byte[] buffer =  Convert.FromBase64String(codedValue);
decoded = Encoding.UTF8.GetString(buffer);
4
répondu Chris Halcrow 2016-07-28 02:40:16