Encoder et décoder une chaîne
Convert travaille sur des octets : choisissez donc explicitement un encodage. Pour tout ce qui sort de votre processus, c’est presque toujours UTF-8 :
using System.Text;
string enc = Convert.ToBase64String(Encoding.UTF8.GetBytes("héllo wörld"));
Console.WriteLine(enc); // aMOpbGxvIHfDtnJsZA==
string dec = Encoding.UTF8.GetString(Convert.FromBase64String(enc));
Console.WriteLine(dec); // héllo wörld
Encoding.Unicode correspond à UTF-16LE et double la taille d’un texte ASCII. Ce n’est le bon choix que si l’autre côté attend de l’UTF-16, par exemple le format de commande encodée PowerShell.
Un usage réel très courant, c’est l’en-tête HTTP Basic Auth :
string token = Convert.ToBase64String(Encoding.UTF8.GetBytes("user:pass"));
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", token);
// Authorization: Basic dXNlcjpwYXNz
Le générateur d’en-tête Basic Auth produit la même valeur dans le navigateur.
Base64 URL-safe : Base64Url dans .NET 9
.NET 9 a ajouté System.Buffers.Text.Base64Url. Il encode sans remplissage et décode avec ou sans :
using System.Buffers.Text;
byte[] d = Encoding.UTF8.GetBytes("<<???>>");
Console.WriteLine(Base64Url.EncodeToString(d)); // PDw_Pz8-Pg
byte[] a = Base64Url.DecodeFromChars("PDw_Pz8-Pg"); // <<???>>
byte[] b = Base64Url.DecodeFromChars("PDw_Pz8-Pg=="); // <<???>>
Il rejette l’alphabet standard : Base64Url.DecodeFromChars("PDw/Pz8+Pg") lève une FormatException. Il existe aussi des surcharges basées sur les spans (EncodeToChars, DecodeFromUtf8, TryDecodeFromChars) qui évitent les allocations.
Sur les runtimes plus anciens, sans le paquet Microsoft.Bcl.Memory, convertissez à la main :
string url = Convert.ToBase64String(d)
.TrimEnd('=').Replace('+', '-').Replace('/', '_'); // PDw_Pz8-Pg
Le décodage demande les remplacements inverses et un remplissage jusqu’à un multiple de 4 :
static byte[] FromBase64Url(string s)
{
s = s.Replace('-', '+').Replace('_', '/');
s = s.PadRight(s.Length + (4 - s.Length % 4) % 4, '=');
return Convert.FromBase64String(s);
}
Encoding.UTF8.GetString(FromBase64Url("PDw_Pz8-Pg")); // <<???>>
Les projets ASP.NET Core peuvent utiliser à la place WebEncoders.Base64UrlEncode de Microsoft.AspNetCore.WebUtilities. Plus de détails sur les deux alphabets dans Base64 ou Base64URL.
Valider une entrée sans exceptions
Convert.FromBase64String lève une System.FormatException sur une entrée invalide. Sous .NET 9, le message est le même dans presque tous les cas :
The input is not a valid Base-64 string as it contains a non-base 64 character,
more than two padding characters, or an illegal character among the padding characters.
Nous avons obtenu ce message pour PDw_Pz8-Pg== (URL-safe), aGk=!! (caractères parasites), aGk (sans remplissage), a et aGk==. La méthode accepte les espaces (" aGk= " et "aGVs\nbG8K" se décodent sans problème) et les bits de remplissage non nuls (aGl=).
Pour éviter les exceptions dans le code critique, utilisez la variante Try avec un tampon, ou Base64.IsValid (.NET 8+) :
Span<byte> buf = stackalloc byte[16];
Convert.TryFromBase64String("aGk=", buf, out int n); // True, n = 2
Convert.TryFromBase64String("aGk", buf, out n); // False, n = 0
System.Buffers.Text.Base64.IsValid("aGk="); // True
System.Buffers.Text.Base64.IsValid("aGk"); // False
Base64Url.IsValid("PDw_Pz8-Pg"); // True
Le tampon doit être assez grand pour la sortie décodée, sinon TryFromBase64String renvoie false même pour une entrée valide. Dimensionnez-le à (s.Length * 3) / 4. Le validateur Base64 et le guide des erreurs aident pour les chaînes qui échouent.
Sauts de ligne (MIME)
Base64FormattingOptions.InsertLineBreaks coupe la sortie à 76 caractères avec \r\n, sans saut de ligne final :
string mime = Convert.ToBase64String(
Encoding.ASCII.GetBytes(new string('x', 60)),
Base64FormattingOptions.InsertLineBreaks);
// "eHh4eHh4...eHh4" (76 chars) + "\r\n" + "eHh4"
FromBase64String relit la forme découpée telle quelle. L’encodeur Base64 MIME produit la même mise en forme.
Encoder et décoder un fichier
Console.WriteLine(Convert.ToBase64String(File.ReadAllBytes("hello.txt"))); // aGVsbG8K
File.WriteAllBytes("copy.txt", Convert.FromBase64String("aGVsbG8K"));
Gros fichiers avec CryptoStream
ToBase64Transform et FromBase64Transform se branchent sur un CryptoStream, ce qui garde la consommation mémoire constante. Malgré l’espace de noms, aucune cryptographie n’intervient :
using System.Security.Cryptography;
using (var input = File.OpenRead("big.bin"))
using (var output = File.Create("big.b64"))
using (var b64 = new CryptoStream(output, new ToBase64Transform(), CryptoStreamMode.Write))
{
input.CopyTo(b64);
}
using (var input = new CryptoStream(File.OpenRead("big.b64"),
new FromBase64Transform(), CryptoStreamMode.Read))
using (var output = File.Create("big.out"))
{
input.CopyTo(output);
}
La libération du CryptoStream vide le dernier bloc et écrit le remplissage ; si vous l’oubliez, la sortie est tronquée. Sur un fichier de test de 300 Ko, les deux sens ont donné le même résultat qu’en mémoire. Pour un contrôle manuel rapide, ouvrez le résultat avec Base64 en fichier.
Pièges courants
- Les préfixes de data URI.
data:image/png;base64,contient:et;, qui déclenchent uneFormatException. Supprimez tout jusqu’à la virgule. - Des jetons URL-safe dans
Convert. Les parties d’un JWT échouent avec le message générique ci-dessus. UtilisezBase64Urlou le décodeur JWT. Encoding.Default. Sous .NET Framework, c’est la page de codes ANSI ; sous .NET Core et versions ultérieures, c’est UTF-8. Du code déplacé de l’un à l’autre change de sortie pour le texte non ASCII.- Base64 n’est pas du chiffrement. Des chaînes de connexion « protégées » par Base64 sont du texte en clair pour n’importe qui. Voir encodage ou chiffrement.
Notes de version
- .NET Framework 1.0+ :
Convert.ToBase64String,FromBase64String,ToBase64Transform. - .NET Core 2.1+ : surcharges à base de spans
Convert.TryFromBase64String,TryToBase64Charset la classe UTF-8System.Buffers.Text.Base64. - .NET 8 :
Base64.IsValid. - .NET 9 :
Base64Url, également disponible pour les cibles plus anciennes viaMicrosoft.Bcl.Memory.
FAQ
Comment corriger « The input is not a valid Base-64 string » ?
Cherchez des caractères URL-safe (-, _), un remplissage manquant et des préfixes de data URI. Convert.FromBase64String n’accepte que l’alphabet standard avec un remplissage correct. Pour les jetons, utilisez Base64Url.DecodeFromChars sous .NET 9, qui accepte les entrées avec ou sans remplissage.
Peut-on utiliser Base64Url sous .NET 8 ou .NET Framework ?
Base64Url est intégré à .NET 9 et versions ultérieures. Pour les cibles plus anciennes, Microsoft fournit le même type dans le paquet Microsoft.Bcl.Memory. Sans lui, convertissez la sortie standard avec TrimEnd('=') et deux appels à Replace.
Pourquoi Encoding.Unicode est-il un mauvais choix pour le Base64 d'un texte ?
Encoding.Unicode, c’est de l’UTF-16LE : hi devient aABpAA== au lieu de aGk=. Utilisez Encoding.UTF8, sauf si le destinataire attend de l’UTF-16, comme le -EncodedCommand de PowerShell.