Wie kann man einen String in seine 8 Bit Bestandteile unterteilen?
Mit den verschiedenen Klassen aus System.Text.Encoding.
Beispiel UTF-8:
string message = "Lorem ipsum dolor sit amet";
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(message)
Wie kann man die 8-Bit Stücke in 6-Bit Stücke unterteilen?
Nimm das kleinste gemeinsame Vielfache (kgv) von 8 und 6.
Der Multiplikator m für 8*m=kgv sagt dir dann, wie viele 8 Bit Blöcke wie vielen 6 Bit Blöcken für 6*M=kgv entsprechen.
8*3=24
6*4=24
Also: 3 Blöcke zu je 8 Bit entsprechen 4 Blöcken zu je 6 Bit.
Dann nimmst du deine 3 Blöcke zu je 8 Bit:
aaaaaaaa bbbbbbbb cccccccc
und teilst diese in 4 Blöcke zu je 6 Bit auf:
aaaaaa aabbbb bbbbcc cccccc
Eine Möglichkeit das zu tun besteht darin, mit einer bitweisen Verschiebung nach links die 3 Bytes zu einem Int32-Wert zusammenzufassen und diesen dann mit bitweisen Verschiebungen nach rechts und einem bitweisen UND in 6 Bit Blöcke aufzuteilen.
Wie kann man dann aus der Base64 Tabelle den dazugehörigen Zeichensatz wieder als String ausgeben?
Ganz einfach: 6 Bit ergeben exakt 64 mögliche Kombinationen (von 0 bis 63).
Der Base64-Zeichensatz hat exakt 64 Zeichen, die jeweils eine Position von 0 bis 63 haben.
Nimm also für jeden 6 Bit Block das Zeichen, das an diesem Index steht.
Ich vermute mal, die Binärwerte werden in einem Array gespeichert,
Muss nicht, aber alles andere wäre Mumpitz.
allerdings habe ich den Workflow mit diesen, im Zusammenhang mit WPF Anwendungen noch nicht gelernt.
Das ist exakt der gleiche wie in jeder anderen Art von Anwendung auch...
P.S.: Beispielcode (weitestgehend ungetestet, aber für plausibel befunden ^^):
string message = "Lorem ipsum dolor sit amet";
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(message)
string charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
System.Text.StringBuilder sb = new System.Text.StringBuilder();
int index, block;
for(index = 0; index + 3 < bytes.Length; index += 3){ // die Nachricht in Blöcken von 3 Bytes durchgehen
block = (bytes[index] << 16) | (bytes[index + 1] << 8) | bytes[index + 2]; //die 3 Bytes zu einer Zahl zusammenfügen
sb.Append(charset[(block >> 18 ) & 0x3f]); // aus dem Charset das Zeichen nehmen, dessen Index den ersten 6 Bit entspricht
sb.Append(charset[(block >> 12 ) & 0x3f]); // das gleiche nochmal für die zweiten 6 Bit
sb.Append(charset[(block >> 6 ) & 0x3f]); // usw...
sb.Append(charset[block & 0x3f]); // ...
}
switch(bytes.Length - index){ // diese Differenz kann 0, 1 oder 2 sein. Bei 0 ist kein weiteres Verfahren nötig.
case 2: // zwei Bytes sind noch übrig
block = (bytes[index] << 16) | (bytes[index + 1] << 8); // siehe oben (nur halt mit nur zwei Bytes)
sb.Append(charset[(block >> 18 ) & 0x3f]);
sb.Append(charset[(block >> 12 ) & 0x3f]);
sb.Append(charset[(block >> 6 ) & 0x3f]);
sb.Append('='); // Füllzeichen anhängen
break;
case 1: // ein btye übrig
block = (bytes[index] << 16); // siehe oben (nur halt mit nur einem Byte)
sb.Append(charset[(block >> 18 ) & 0x3f]);
sb.Append(charset[(block >> 12 ) & 0x3f]);
sb.Append('='); // Füllzeichen anhängen
sb.Append('='); // Füllzeichen anhängen
break;
}
System.Console.WriteLine(sb.ToString());