2014-10-14 24 views
55

Voglio ottenere la codifica sicura di Base64 URL in C#. In Java, abbiamo la libreria comune Codec che mi fornisce una stringa codificata sicura per l'URL. Come posso ottenere lo stesso usando C#?Come raggiungere la codifica sicura di Base64 URL in C#?

byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("StringToEncode"); 
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes); 

Il codice precedente converte in Base64, ma pastiglie ==. C'è un modo per ottenere la codifica sicura dell'URL?

+0

Non puoi semplicemente usare 'Url.Encode' nella stringa in' BASE64'? –

+0

In quale classe Url del namespace è presente in C#? –

+0

Dai un'occhiata: http://msdn.microsoft.com/en-us/library/system.web.httputility.urlencode%28v=vs.110%29.aspx È necessario fare riferimento all'assembly 'System.Web'. –

risposta

98

È comune a scambiare semplicemente l'alfabeto per l'utilizzo negli URL, in modo che non sia necessario eseguire la codifica%; solo 3 dei 65 caratteri sono problematici - +, / e =. le sostituzioni più comuni sono - al posto di + e _ al posto di /. Per quanto riguarda il padding: è sufficiente rimuoverlo (il =); puoi dedurre la quantità di riempimento necessaria. All'altra estremità: basta invertire il processo:

string returnValue = System.Convert.ToBase64String(toEncodeAsBytes) 
     .TrimEnd(padding).Replace('+', '-').Replace('/', '_'); 

con:

static readonly char[] padding = { '=' }; 

e per invertire:

string incoming = returnValue 
    .Replace('_', '/').Replace('-', '+'); 
switch(returnValue.Length % 4) { 
    case 2: incoming += "=="; break; 
    case 3: incoming += "="; break; 
} 
byte[] bytes = Convert.FromBase64String(incoming); 
string originalText = Encoding.ASCII.GetString(bytes); 

La domanda interessante, tuttavia, è: è presente lo stesso approccio che usa la "libreria di codec comune"? Sarebbe sicuramente una prima cosa ragionevole da testare - questo è un approccio abbastanza comune.

+1

In Common Codec stanno usando [0-9a-zA-Z_-] Character for url modalità sicura. –

+0

questo è anche menzionato nella pagina wiki per Base64 sotto le applicazioni URL. http://en.wikipedia.org/wiki/Base64 – wonster

+1

Hai anche questa funzione 'http://stackoverflow.com/questions/1886686/c-sharp-byte-to-url-friendly-string' che fa tutto il duro lavoro per te – toy4fun

0

Ecco un altro metodo per decodificare un url-safe base64 è stato codificato nello stesso modo con Marc. Solo non capisco perché 4-length%4 ha funzionato (lo fa).

Come segue, solo la lunghezza del bit dell'origine sono multipli comuni di 6 e 8, base64 non aggiunge "=" al risultato.

1 2 3 4 5 6 7 8|1 2 3 4 5 6 7 8|1 2 3 4 5 6 7 8 
1 2 3 4 5 6|1 2 3 4 5 6|1 2 3 4 5 6|1 2 3 4 5 6 
       "=="   "=" 

in modo che possiamo farlo al contrario, se la lunghezza del bit di risultato non può divisibile per 8, è stato aggiunto:

base64String = base64String.Replace("-", "+").Replace("_", "/"); 
var base64 = Encoding.ASCII.GetBytes(base64String); 
var padding = base64.Length * 3 % 4;//(base64.Length*6 % 8)/2 
if (padding != 0) 
{ 
    base64String = base64String.PadRight(base64String.Length + padding, '='); 
} 
return Convert.FromBase64String(base64String); 
5

Usa System.Web.HttpServerUtility.UrlTokenEncode (byte) per codificare e System.Web.HttpServerUtility.UrlTokenDecode (byte) da decodificare.

+3

Questo non fornisce una codifica Base64 conforme agli standard URL conforme a RFC4648. Vedi anche [questo Q & A] (http://stackoverflow.com/questions/26732145/c-base64url-according-to-rfc4648). ** Usare con cautela. ** –

27

È possibile utilizzare la classe Base64UrlEncoder dallo spazio nomi Microsoft.IdentityModel.Tokens.

const string StringToEncode = "He=llo+Wo/rld"; 

var encodedStr = Base64UrlEncoder.Encode(StringToEncode); 
var decodedStr = Base64UrlEncoder.Decode(encodedStr); 

if (decodedStr == StringToEncode) 
    Console.WriteLine("It works!"); 
else 
    Console.WriteLine("Dangit!"); 
+0

Questo è molto più pulito della risposta accettata. Qualche lato negativo? – taktak004

+3

Solo una nota: Microsoft.IdentityModel.Tokens è un pacchetto NuGet che deve essere scaricato. –

-1

Un sacco di buone risposte qui. Sbarazzarsi di +,/e = è abbastanza semplice su ogni stringa con String.Replace ma normalmente ho una classe helper che rimuove i caratteri speciali nella maggior parte dei miei progetti.

public static class Helpers 
    { 
     public static string RemoveSpecialCharacters(string str) 
     { 
      return Regex.Replace(str, "[^a-zA-Z0-9]", "", RegexOptions.Compiled); 
     } 
    } 

Ho usato questo per aiutarmi a creare un token.

using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) 
      { 
       byte[] data = new byte[ByteLength]; 
       rng.GetBytes(data); 
       return Helpers.RemoveSpecialCharacters(Convert.ToBase64String(data)); 
      } 
+0

Se si eliminano alcuni caratteri, alcuni dati andranno persi e la stringa non può più essere decodificata – samfromlv

2

basato fuori le risposte qui con alcuni miglioramenti delle prestazioni, abbiamo pubblicato un molto facile da usare url-safe base64 implementation to NuGet con il codice sorgente available on GitHub (MIT licenza).

L'uso è facile come

var bytes = Encoding.UTF8.GetBytes("Foo"); 
var encoded = UrlBase64.Encode(bytes); 
var decoded = UrlBase64.Decode(encoded);