# Base64 funktioniert nicht, aber btoa funktioniert



## krgewb (11. Feb 2021)

Ich hole ein Bild anhand der URL und wandle es in Base64 um. Im Frontend füge ich dann nur noch "data:image/jpeg;base64," am Anfang ein.

```
ResponseEntity<String> exchange = restTemplate.exchange(urlOfImage, HttpMethod.GET, entity, String.class);
String s = exchange.getBody();
String stringInBase64 = Base64.getEncoder().encodeToString(s.getBytes());
```
Das Bild kann nicht angezeigt werden. 

Wenn ich jedoch den unverschlüsselten String ( s ) zurückgebe, dann funktioniert es. Dazu verwende ich im Frontend die Javascript-Methode btoa.








						Window btoa() Method
					

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.




					www.w3schools.com


----------



## mrBrown (11. Feb 2021)

Was steht denn in `s` drin? Ein Bild in einem *nicht* Base64-Encodierten String speichern klingt nach keiner sehr guten Idee.


----------



## krgewb (11. Feb 2021)

Laut Entwicklerwerkzeuge von Firefox beginnt der String mit "ÿØÿà\u0000\u0010JFIF\u0000"


----------



## LimDul (11. Feb 2021)

Das Problem dürfte sein, dass getBytes ohne Encoding dann "zufällig" ist, welches Encoding gewählt wird. (Plattform Default).

Wenn irgendwer das Bild in einen String schreibt (Wer macht sowas? Da bin ich bei @mrBrown) dann muss beim zurückwandeln das exakt gleiche Encoding gewählt werden.


----------



## MoxxiManagarm (11. Feb 2021)

LimDul hat gesagt.:


> Wer macht sowas?


Beispiel 1:

QR-Codes. Die werden als Daten *erzeugt*. Du hast also kein Bild, was du von einer Resource lädst, du hast nur "Daten". Die speichert man dann gerne in einen base64-encoded String und gibt diesen String dann an das img-Tag im html um den generierten Code anzuzeigen.

Beispiel 2:

Du hast ein html mit Bildern. Dieses html möchtest du nun von einem html-to-pdf-Renderer in ein PDF umwandeln. Dieser pdf-Renderer hat keinen Zugriff auf externe Resourcen, alles muss im html *eingebettet* sein. Das schaffst du denke ich nur mit dem base64-codierten Bild im img Tag

Beispiel 3:

Ich habe Server Applikationen gesehen, die speichern z.B. Avatare von Benutzern in diesem Format in ihrer *Datenbank* und geben es so der Client Applikation zurück. Dann ist es auch am einfachsten den String zu nehmen wie er ist und ihn so in das img Tag zu packen, wenn der Avatar angezeigt werden soll.


----------



## mrBrown (11. Feb 2021)

MoxxiManagarm hat gesagt.:


> Beispiel 1:
> 
> QR-Codes. Die werden als Daten *erzeugt*. Du hast also kein Bild, was du von einer Resource lädst, du hast nur "Daten". Die speichert man dann gerne in einen base64-encoded String und gibt diesen String dann an das img-Tag im html um den generierten Code anzuzeigen.
> 
> ...


Aber in allen Beispielen ist der String zumindest irgendwie sinnvoll kodiert, und nicht nur ein String erzeugt aus den reinen bytes der Grafik? Also nicht einfach nur "ich nehme die reinen Bytes und behandle die jetzt einfach als String, egal was drin steht", sondern ein sinnvolles bytes zu String-konvertieren.

Das Beispiel von @krgewb enthält ja auch sowas wie '\u0000'...


----------



## kneitzel (11. Feb 2021)

MoxxiManagarm hat gesagt.:


> Die speichert man dann gerne in einen base64-encoded String


Das ist das wichtige - es wird in einem base64-encoded String gespeichert. Das ist dann auch ok.

Aber hier liegen die Byte-Daten so in einem String. Und das kann nicht nur durch diverse encoding/decoding Aktionen zu Problemen führen sondern das Encoding oder Decoding kann auch fehlschlagen.

Siehe dazu z.B. https://unicode.org/faq/utf_bom.html


> Are there any byte sequences that are not generated by a UTF? How should I interpret them?





> A: None of the UTFs can generate _every_ arbitrary byte sequence. For example, in UTF-8 every byte of the form 110xxxxx_2_ _must_ be followed with a byte of the form 10xxxxxx_2_. A sequence such as <110xxxxx_2_ 0xxxxxxx_2_> is illegal, and must never be generated. When faced with this illegal byte sequence while transforming or interpreting, a UTF-8 conformant process must treat the first byte 110xxxxx_2_ as an illegal termination error: for example, either signaling an error, filtering the byte out, or representing the byte with a marker such as FFFD (REPLACEMENT CHARACTER). In the latter two cases, it will continue processing at the second byte 0xxxxxxx_2_.
> 
> A conformant process _must not_ interpret illegal or ill-formed byte sequences as characters, however, it may take error recovery actions. No conformant process  may use irregular byte sequences to encode out-of-band information.



Daher wäre ich hier auch deutlich vorsichtiger und würde so Interfaces / APIs überdenken. Zumal ein korrekter Weg (base64 encoding) ja auch schon genannt ist ...


----------



## LimDul (11. Feb 2021)

MoxxiManagarm hat gesagt.:


> Beispiel 1:
> 
> QR-Codes. Die werden als Daten *erzeugt*. Du hast also kein Bild, was du von einer Resource lädst, du hast nur "Daten". Die speichert man dann gerne in einen base64-encoded String und gibt diesen String dann an das img-Tag im html um den generierten Code anzuzeigen.
> 
> ...


Einen Base-64 kodierten String => Klar.
Die Binärdaten eines Bildes unencodiert in einem String speichern => WARUM?


----------



## MoxxiManagarm (11. Feb 2021)

Achso, aber er hat doch btoa gesprochen, was in js eine base64 Funktion ist


----------



## LimDul (11. Feb 2021)

Ok, das wusste ich nicht. Dann ist der gesamte Code da oben Unfug, weil dann wird der String ja nochmal Base 64 encodierit.


----------



## mrBrown (11. Feb 2021)

Soweit ich verstanden hab ist zumindest der String `s` in dem Java-Code kein Base-64, sondern wirklich unenkodierte Binärdaten. Sonst würde ja noch sowas irgendwo rauskommen: 


krgewb hat gesagt.:


> String mit "ÿØÿà\u0000\u0010JFIF\u0000"


----------

