2009-08-04 24 views
102

Quiero basar64 codificar datos para ponerlos en una URL y luego decodificarlos dentro de mi HttpHandler.Código para descodificar/codificar una base64 URL modificada

He encontrado que Base64 Encoding permite un carácter '/' que estropeará mi coincidencia UriTemplate. Luego encontré que existe un concepto de "Base64 modificado para URL" de la wikipedia:

Existe un Base64 modificado para la variante de URL, donde no se usará relleno '=', y '+' y '/' los caracteres de Base64 estándar se reemplazan respectivamente por '-' y '_', por lo que el uso de codificadores/decodificadores de URL ya no es necesario y no tiene impacto en la longitud del valor codificado, dejando la misma forma codificada intacta para usar en bases de datos relacionales , formularios web e identificadores de objeto en general.

Usando .NET Quiero modificar mi código actual de hacer codificación y decodificación básica de base64 a usar el método "base64 modificado para URL". ¿Alguien ha hecho esto?

para decodificar, sé que comienza con algo como:

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

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

// My normal base64 decoding now uses encodedText 

Pero, tengo que añadir potencialmente, una o dos caracteres '=' al extremo que se ve un poco más complejo.

Mi lógica de codificación debe ser un poco más 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('/', '_'); 

he visto la entrada Stackoverflow Guid to Base64 for URL, pero que tiene una longitud conocida y por lo tanto se puede codificar el número de signos igual necesarios al final.

+0

@Kirk: Ajusta mi respuesta con la matemática probad. – AnthonyWJones

Respuesta

55

Esto debería almohadilla a cabo correctamente: -

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

Bah, me ganaste. Eliminaré mi publicación porque parece casi como si te hubiera copiado :) – AaronLS

+2

¿No se agregarán tres caracteres '='? Parece que solo habrá 0, 1 o 2 de estos. –

+1

@Kirk: si agrega 3 caracteres, la cadena base64 ya está corrupta. Supongo que sería una buena idea validar la cadena, solo debería contener los caracteres esperados y Length% 4! = 3. – AnthonyWJones

168

también comprobar clase HttpServerUtility con UrlTokenEncode y UrlTokenDecode métodos que está manejando URL segura codificación Base64 y decodificación.

Nota 1: El resultado no es una cadena Base64 válida. Algunos caracteres inseguros para URL son reemplazados.

Nota 2: El resultado difiere del algoritmo base64url en 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); 
} 
+0

Gracias por el consejo. ¡Lo intentaré la próxima vez! –

+11

Su consejo fue el glorioso final de una búsqueda de múltiples horas y mechones para encontrar la respuesta. gracias – Praesagus

+0

Esto hace el truco ... –

18

me golpeó aquí en la búsqueda de código para hacer de codificación/decodificación de base64url codificación que es poco diferente de base 64 como se explica en la pregunta.

Se encontró el fragmento de código de C# en este documento. JSON Web Signature ietf draft

+1

Esta fue la única solución que funcionó para mí al analizar un mensaje en GMail API v1 (Mensaje.Raw) – HeyZiko

18

No hay suficientes puntos para comentar, pero en caso de que ayude, el fragmento de código que Sushil encontró en el enlace proporcionado (JSON Web Signature ietf draft) funciona para codificar Base 64 como parámetro en URL.

fragmento copiado a continuación para aquellos que son perezosos:

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 
    } 
+0

esto es compatible con Xamarin por no usar System.Web –

3

En comparación con la respuesta aceptada, aquí es cómo lo haría fundamentalmente decodificación una URL codificada en base64, usando C#:

Decode :

string codedValue = "base64encodedUrlHere"; 

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

quizás si proporciona más detalles y compara la respuesta aceptada puede obtener un voto favorable - gracias –

Cuestiones relacionadas