Base64 Umwandlung streikt, aber PHP kann es

  • VB.NET

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von MaxeStudios.

    Base64 Umwandlung streikt, aber PHP kann es

    Liebe Paradiser,

    ich kämpfe mit einem Base64 Umwandlungsproblem. In in php funktioniert es, in VB.net nicht. Ich verwende folgenden Standard-Code:

    Dim nBytes() As Byte = System.Convert.FromBase64String(txtInput.Text)

    Hier kommt der folgende Fehler:

    "Die Eingabe ist keine gültige Base-64-Zeichenfolge, da sie ein Nicht-Base-64-Zeichen, mehr als zwei Leerstellen oder in den Leerstellen ein Zeichen enthält, das ungültig ist."

    Jedoch ergab sämtliche Recherche keine Lösung. Der Input lautet:

    eyJhbGciOiJFUzI1NiJ9.X1IxLUFUMV9rYXNzZTFfZnQzQzA1IzE1MzY2XzIwMTctMTEtMDJUMDg6NDA6NTNfMiwzMF8wLDAwXzAsMDBfMCwwMF8wLDAwXzIxRXNYZDg9XzZiYTk3MmU2X2I1bnVNNXBHSS9BPQ.u7mpRXUm1NAj0iQkXgXXLUpU9bnFAqqswLtyCG0LtqiQRiVGeZOy2FwRG7o2sp8nevpcql8X7944ZfH3Y5qIGw

    Der Gag ist: VB.Net schmeißt den Fehler, aber trage ich die Zeile in einem Webtool, wie z.B. base64decode.org/ o.a. ein, bekomme ich die korrekte Umwandlung ohne Fehlermeldung. Die Beschreibung des Fehlers gibt mir keinen Ansatzpunkt, da weder Leerzeichen noch Nicht-Base-64-Zeichen vorhanden sind.

    Wie kann ich VB.net die Umwandlung beibringen?

    Vielen Dank für Eure Hilfe...!
    @Anke71 In diesem String kommen zwei Pinkte "." vor, die da nicht hingehören.
    Wenn Du die rausnimmst, lässt sich der Text konvertieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @petaod Das ist in resx-Dateien so, also eher für den Designer.
    Ich hab den Text ohne die Punkte konvertiert.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo, Danke erstmal für die Hilfe.

    Ich habe die beiden Punkte entfernt. Dann läßt sich der String umwandeln, aber das Ergebnis ist ein völlig anderes als in PHP:

    VB.NET:
    ≻污≧∺卅㔲∶彽ㅒ䄭ㅔ歟獡敳弱瑦䌳㔰ㄣ㌵㘶㉟㄰ⴷㄱ〭吲㠰㐺㨰㌵㉟㌬弰ⰰ〰た〬弰ⰰ〰た〬弰ㄲ獅摘㴸㙟慢㜹攲弶㕢畮㕍䝰⽉㵁묋钚剗䵭㴂䈢牝ꗔ孏傜ꨪௌ₷킆檻҉呢饧ⴻ솅묑殣꽷쪥ﵾ蛣Ὗ㥶膨�

    PHP:
    {"alg":"ES256"}_R1-AT1_kasse1_ft3C05#15366_2017-11-02T08:40:53_2,30_0,00_0,00_0,00_0,00_21EsXd8=_6ba972e6_b5nuM5pGI/A=
    WRmM="BE]rԥO[P*
    лjbTg;-k)wʥ~_v9

    Die untere Version benötige ich. Könnte der Ausgangsstring vielleicht gar kein Base64 sein? Wir "verschlüsseln" die Daten nicht selbst, sondern eine Fremdsoftware.

    -------------------
    ​Nachtrag: hier spielt der Code danach die entscheidende Rolle: mit UTF-8

    txtOutput.Text = System.Text.Encoding.UTF8.GetString(nBytes) statt txtOutput.Text = System.Text.Encoding.Unicode.GetString(nBytes)

    ​funktioniert es nun.






    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Anke71“ ()

    Ich würde behaupten das sind 3 getrennte Base64 strings(evtl. ist das letzte nicht mal base64, auf jeden Fall scheint der output kein sinnvoller string)
    Also trenn den string an den punkten in drei strings auf.
    Anschließend musst du vlt. für jeden string, bevor du die base64 decodierung machst folgendes anwenden:

    C#-Quellcode

    1. str = str+new string('=',(3-str.Length % 3));

    das sorgt dafür, dass die string länge ein vielfaches von 3 ist und was eben fehlt mit '=' aufgefüllt wird, anscheinend gehört sich das nämlich so
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    jvbsl schrieb:

    str = str+new string('=',(3-str.Length % 3));
    funktioniert leider nicht, die Länge muss Mod 4 = 0 sein:

    MSDN schrieb:

    The length of s, ignoring white-space characters, is not zero or a multiple of 4.
    Dies funktioniert:

    VB.NET-Quellcode

    1. If txt.Length Mod 4 <> 0 Then
    2. txt &= New String("="c, (4 - txt.Length Mod 4))
    3. End If

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    ne funktioniert auch nur bedingt, wenn nämlich um 3 gepaddet wird ists auch falsch...

    C#-Quellcode

    1. str = str+new string('=',(-str.Length % 4) % 3);

    aber interessant, da hab ich wohl wiki bissl falsch verstanden gehabt, dachte soll einfach auf 3 gepaddet werden hm...

    Aber wie es aussieht ist der Code eh fürn arsch, .Net scheint kein Padding zu benötigen zumindest nicht wenn ichs beim rextester ausprobier...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    jvbsl schrieb:

    .Net scheint kein Padding zu benötigen
    Doch.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim txt1 = "eyJhbGciOiJFUzI1NiJ9"
    3. Dim txt2 = "X1IxLUFUMV9rYXNzZTFfZnQzQzA1IzE1MzY2XzIwMTctMTEtMDJUMDg6NDA6NTNfMiwzMF8wLDAwXzAsMDBfMCwwMF8wLDAwXzIxRXNYZDg9XzZiYTk3MmU2X2I1bnVNNXBHSS9BPQ"
    4. Dim txt3 = "u7mpRXUm1NAj0iQkXgXXLUpU9bnFAqqswLtyCG0LtqiQRiVGeZOy2FwRG7o2sp8nevpcql8X7944ZfH3Y5qIGw"
    5. Me.AppendText(txt1)
    6. Me.AppendText(txt2)
    7. Me.AppendText(txt3)
    8. 'Me.AppendText(txt1 & txt2 & txt3)
    9. End Sub
    10. Private Sub AppendText(txt As String)
    11. If txt.Length Mod 4 <> 0 Then
    12. txt &= New String("="c, (4 - txt.Length Mod 4))
    13. End If
    14. Dim nBytes() As Byte = System.Convert.FromBase64String(txt)
    15. Me.RichTextBox1.AppendText(System.Text.Encoding.UTF8.GetString(nBytes))
    16. Me.RichTextBox1.AppendText(Environment.NewLine)
    17. End Sub
    Das gibt sonst die Padding-Exception bei txt2 und txt3.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Aber wie gesagt dein code ist dann trotzdem nicht korrekt weil 3 mal = angefügt werden kann, was auch nicht passieren darf. Deshalb mein obiger code sparst dir azch das branching durch das if, hast dafür evtl ne unnötige allocation, was da jetzt schlimmer ist kann ich nicht sagen.
    Zur not haust du meinen code in dein if, wenn man allocs sparen will(bzw. Müsste man dann eigt native rangehen kann man dann auf 1 alloc reduzieren)
    Und ja ich mag Mikrooptimierung^^
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    @jvbsl Ich hab eben noch mal in meinen Bitmap-Code nachgesehen, das geht auch ohne if:

    C#-Quellcode

    1. int padding = (4 - width) & 3;
    Jou.
    Das mit dem 3er Rhythmus hab ich mal getestet, das ist echt merkwürdig:
    Code

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim bb() As Byte = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    3. Dim by = bb.ToList()
    4. Dim bb64 = Convert.ToBase64String(bb)
    5. Me.AppendText(bb64)
    6. For i As Byte = 0 To 9
    7. by.Add(i)
    8. bb64 = Convert.ToBase64String(by.ToArray())
    9. Me.AppendText(bb64)
    10. Next
    11. End Sub
    12. Private Sub AppendText(txt As String)
    13. Me.RichTextBox1.AppendText(txt)
    14. Me.RichTextBox1.AppendText(Environment.NewLine)
    15. End Sub
    Ausgabe

    Quellcode

    1. AAECAwQFBgcICQ==
    2. AAECAwQFBgcICQA=
    3. AAECAwQFBgcICQAB
    4. AAECAwQFBgcICQABAg==
    5. AAECAwQFBgcICQABAgM=
    6. AAECAwQFBgcICQABAgME
    7. AAECAwQFBgcICQABAgMEBQ==
    8. AAECAwQFBgcICQABAgMEBQY=
    9. AAECAwQFBgcICQABAgMEBQYH
    10. AAECAwQFBgcICQABAgMEBQYHCA==
    11. AAECAwQFBgcICQABAgMEBQYHCAk=

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    bei width von 1 bzw. 5 will er aber um 3 padden, das & 3 ersetzt nur das modulo 4 nicht aber das modulo 3.
    somit ist das & tatsächlich nicht ganz unsinnvoll, vorallem weil ich vergessen hab, dass das programmier modulus für negative Zahlen nicht dem mathematischen enstpricht, deshalb geht das oben gar nicht, mit dem und gehts aber ;)

    C#-Quellcode

    1. int padding = ((-width) & 3) % 3

    & ist laut eigenen tests zumindest auf meinem prozessor schneller als modulus in C#(C++ optimierts automatisch zu verundung)

    Wir machen hier sowieso viel zu viel aus ner Kleinigkeit^^
    Edit gerade noch rausgefunden

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/78f735fc-6432-48e8-999a-73f631665f36/base64-padding-character-issue?forum=clr schrieb:

    If Base64 string is 5 character long then we the string is corrupted already. So there cannot be a case when the base64 string length be 1, 5, 11, 16 etc.

    also evtl. ist das % 3 am ende tatsächlich nicht notwendig. wobei bei 9 halt auch 3 als padding rauskommt, was der MSDN thread oben nicht als ungültig genannt hat, also keine Ahnung^^ Außerdem scheint das 4er padding von .Net allein ein Problem zu sein. Ich vermute, dass die Implementierung intern ints verwendet aus Performanzgründen und somit um nicht in ungeschütztem Speicher zulesen das 4er und 4er padding erzwingt, aber keine ahnung^^
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „jvbsl“ ()

    https://www.vb-paradise.de/index.php/Thread/125739-VB-NET-Base64-Codierung/


    Edit: Ich weiß nicht ob es für andere aufrufbar ist, da ich nicht weiß ob dieser Beitrag wirklich schon freigeschaltet wurde, aber ich denke schon da ich diesen aufrufen kann :)

    ╔══╦═╦╦╦═╦══╦══╦╗╔╦═╦╦═╦══╗
    ║║║║╩╠..╣╦╬╗╚╬╗╔╣╚╝║╠║║║╠╗╚╣
    ╚╩╩╩╩╩╩╩═╩══╝╚╝╚══╩═╩╩═╩══╝