Base64-decode a string using NetEncoding in Delphi XE7?
Asked Answered
L

1

6

In Delphi XE7 Update 1, when trying to execute this code in a VCL program:

uses System.NetEncoding;
...
tempstring := TNetEncoding.Base64.Decode(tempstring);

I get this error message:

Error message

So how can I base64-decode a string using NetEncoding?

Leash answered 23/2, 2015 at 8:59 Comment(0)
E
10

You are calling the Decode overload that accepts base64 encoded text and returns a string. The way that Decode method is implemented is as follows:

  1. Decode the base64 to binary.
  2. Treat the binary as UTF-8 encoded text.
  3. Decode the UTF-8 bytes to text.

Your error message indicates that the binary that results from step 1 is not valid UTF-8. In order to work out why this is so requires knowledge of where the base64 encoded text originated.

Your current code assumes that the following process took place to create the base64 encoded value:

  1. Encode some text to UTF-8 bytes.
  2. Base 64 encode those bytes.

The problem is not necessarily in your code to decode. The problem is that your decoding does not match the process that originally encoded. The fault could lie either in the original encoding, or the decoding. You need to check how the base64 value was encoded. Was it encoded using the steps described above?

If I had to guess, I would suspect that the original data was not in fact textual. My guess is that the original data is binary, that is a stream of bytes. I suspect that you started from some code which held a binary data in an AnsiString variable. It is very common to see Delphi code that abuses strings in this way. For historical reasons it seems to have been written in to the lore that AnsiString can be used to hold binary data. I guess this all started when Delphi 2 introduced AnsiString and at that time there were no dynamic arrays.

Anyway, if you have previously been using AnsiString to hold binary data then you should take this opportunity to stop doing so. Use TBytes, for instance, for that purpose. In which case you would use:

var
  bytes: TBytes;
....
bytes := TNetEncoding.Base64.DecodeStringToBytes(...);

to decode your base64 value to binary.

So, suppose that the base64 that you have is actually ANSI encoded text. Then you would decode it like this:

var
  bytes: TBytes;
  text: string;
....
bytes := TNetEncoding.Base64.DecodeStringToBytes(...);
text := TEncoding.ANSI.GetString(bytes);

This assumes the prevailing ANSI code page on the machine on which you decode. If you need to specify an ANSI code page then you might write it like this:

var
  bytes: TBytes;
  text: string;
  Encoding: TEncoding;
....
bytes := TNetEncoding.Base64.DecodeStringToBytes(...);
Encoding := TEncoding.GetEncoding(CodePage);
try
  text := Encoding.GetString(bytes);
finally
  Encoding.Free;
end;

As you can see, I am now reduced to guessing. If you want to make progress you will find out how your data was encoded.

Edam answered 23/2, 2015 at 9:23 Comment(10)
So could it work if I do the 3 steps myself? Example: 1. Decode the base64 to binary. 2. Detect the encoding of the binary. 3. Choose a method to decode. How could this be done in code? Or is there another base64-decode method which does not have this limitation of TNetEncoding?Leash
TNetEncoding is not limited. You need to know how the original value was encoded. That's your next move. I have a feeling that you don't really understand what base64 is. Do you understand that base64 encodes binary to text, and decodes text to binary? I ask this because I think it is important to establish some common ground.Edam
I understand what base64 is. The problem is: The base64 text I try to decode was created by an unknown instance, not by myself. So I don't know how it was encoded. However, if I decode it with one of the many online base64 decoders, it gets decoded without problems.Leash
If you won't tells us what the base64 is, or what the result of the decode should be, then it's hard for us to be more specific. Everything that I have told you in my answer is accurate. Let me try again. Why are you attempting to decode it to text? Why aren't you decoding to binary?Edam
I cannot tell the base64 text as it is confidential. As I have said, when I decode it with an online base64 decoder, I get exactly the correct text.Leash
Remember that when you decode base64, the result is binary. So, if you are seeing text, that binary has then been decoded to text using some text encoded. Which text encoding was used? Are you decoding random bits of base64, or do you have an idea where the base64 comes from? Will the person that encoded the base64 talk to you? I am quite astounded with this conversation. Presumably you asked because you didn't understand. Right?Edam
I am very sorry! I read the base64 text from a file and forgot to clean it up as there were zero characters before the actual base64 text. I am so sorry! I think I got not enough sleep lately... - Should I delete the question or accept your answer?Leash
Well, you asked a question, and I spent quite a lot of time and effort answering it, and trying to help you understand. It's up to you whether or not you think my efforts deserve reward. I'd regard deletion as a rather ungracious act.Edam
I asked because I possibly could infringe some rules. Of course I very much appreciate your time and effort, as I always appreciate your answers. Thank you!Leash
Thanks for asking! I appreciate that thought.Edam

© 2022 - 2024 — McMap. All rights reserved.