base64 encode - Home Made tramite LINQ

Sono passati due mesi dal mio ultimo post sul blog e mi scuso, ma non sono stati mesi facili. Oggi si riprende a fare sul serio con un articolo a tema base64. Tutti l’abbiamo sicuramente usato, ma in quanti si sono posti la domanda: come si crea sotto?

Nei giorni scorsi ho deciso di “sporcarmi un attimo le mani” e divertirmi cercando di ricostruirne il procedimento utilizzando LINQ. Ci sono riuscito? Credo di si e di seguito vi voglio riportare il codice da me scritto.

Prima di passare al prossimo step ci tengo a dire una cosa. Ho eseguito dei test generando DUECENTOMILA stringhe casuale di lunghezze casuale e confrontato il risultato tra il mio procedimento ed il “canonico”. Ho avuto zero elementi marcati come errore. Direi non male, vero? (vi consiglio di arrivare in fondo per capire come)

base64 - Teoria

Prima di cominciare, vi ricordate quali sono gli otto passaggi per creare il valore base64 dato il testo in ingresso?

  • Separare tutti i caratteri della stringa fornita
  • Convertire ogni carattere in binario
  • Concatenare tutti i binari ottenuti dal punto precedente
  • Rompere la super stringa binaria in sotto stringhe da sei caratteri
  • Aggiungere “00” davanti ad ogni stringa ottenuta
  • Convertire ogni singola stringa in numero decimale
  • Prendere il carattere corrispondente ad ogni singolo numero
  • Unirli per ottenere il base64

EXTRA: aggiungere il carattere = sino a quando la stringa ottenuta non avra’ una lunghezza multiplo di quattro.

base64 - codice

1
2
using System;
using System.Linq;

Arrivati a questo punto non dobbiamo fare altro che utilizzare la classe Base64Converter scritta per l’articolo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class Base64Converter
{
    private const char ZERO_CHAR = '0';
    private const int TWO = 2;
    private const int FOUR = 4;
    private const int SIX = 6;
    private const int EIGHT = 8;

    private const string UPPERCASE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private const string LOWERCASE_LETTERS = "abcdefghijklmnopqrstuvwxyz";
    private const string DIGITS = "0123456789";
    private const string SPECIAL_SYMBOLS = "+/";
    private const string EQUAL = "=";

    private readonly string _allChars = string.Empty;

    public Base64Converter()
    {
        _allChars = $"{UPPERCASE_LETTERS}{LOWERCASE_LETTERS}{DIGITS}{SPECIAL_SYMBOLS}";
    }

    public string ConvertToWithLinq(string text)
    {
        var groups = text
            .ToCharArray();

        var binaries = groups
            .Select(x => Convert.ToString(x, TWO).PadLeft(EIGHT, ZERO_CHAR))
            .ToList();

        var allBinaries = string.Join(string.Empty, binaries);

        var binaryGroups = allBinaries
            .Select((x, i) => i)
            .Where(i => i % SIX == 0)
            .Select(i => String.Concat(allBinaries.Skip(i).Take(SIX)))
            .Select(i => i.PadRight(SIX, ZERO_CHAR))
            .Select(i => i.PadLeft(EIGHT, ZERO_CHAR))
            .ToList();

        var decimalGroups = binaryGroups
            .Select(x => Convert.ToInt32(x, 2))
            .ToList();

        var charGroups = decimalGroups
            .Select(x => _allChars[x])
            .ToList();

        string result = string.Join(string.Empty, charGroups);

        while (result.Length % FOUR != 0)
        {
            result += EQUAL;
        }

        return result;
    }
}

Come avrete visto l’operazione da svolgere è veramente semplice. Se non siete convinti del codice appena scritto, vi lascio anche il metodo classico in modo da non fare mancare nulla a nessuno:

1
2
3
4
5
private string ConvertTo(string plainText)
{
    var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
    return Convert.ToBase64String(plainTextBytes);
}

Per quanto riguarda l’asterisco messo ad inizio articolo, vi invito a guardare Base64Converter.cs sul mio GitHub dove potrete trovare anche un progetto di UnitTest utilizzato per il test massimo da me citato.

Ora non vi resta che attendere i prossimi articoli a tema perche’ ci saranno novita’ molto interessanti!

Happy Coding!