1

I'm looking to encode a string variable to UTF-16LE and base64 , the problem is that I find nothing about how to do UTF-16LE in Delphi.

Example in Python :

from base64 import b64encode
b64encode('my text'.encode('UTF-16LE'))

Example in Ruby :

require "base64"
Base64.encode64('my text'.force_encoding('UTF-16LE'))

As I can do this in Delphi?

Updated :

procedure TFormTest.btnTestClick(Sender: TObject);
var
  dest, src: TEncoding;
  srcBytes, destBytes: TBytes;
  Encoder: TIdEncoderMime;
begin
  Encoder := TIdEncoderMime.Create(nil);
  src := TEncoding.Unicode;
  srcBytes := src.GetBytes(Edit1.Text);
  Edit2.Text := Encoder.EncodeBytes(srcBytes);
  FreeAndNil(Encoder);

end;

Is a valid base64 UTF-16LE created?

Powershell tells me it is invalid

Command to use :

(New-Object System.Net.WebClient).DownloadFile('http://localhos/update_program.exe','updater.exe'); Start-Process 'updater.exe'

Output error :

Missing expression after unary operator '-'.
13
  • 1
    In Delphi versions 2009 and above, strings are in UTF-16LE. You want a method to do B64 encoding. You can probably find something in one of the Indy units. Commented Jul 15, 2016 at 15:47
  • 1
    Delphi is little-endian, and 'UTF-16LE' is default Delphi encoding for strings. Commented Jul 15, 2016 at 15:48
  • TEncoding.Unicode.GetBytes(str) to encode as UTF-16LE. Then use one of the many base64 encoders. Try some websearch. Commented Jul 15, 2016 at 16:06
  • My new source is a valid base64 UTF-16LE ? Commented Jul 15, 2016 at 16:29
  • A program tells me it is invalid Commented Jul 15, 2016 at 16:30

1 Answer 1

2

What you have shown is technically correct. The String gets encoded to a UTF-16LE byte array first, and then the bytes get base64 encoded.

Since you are calling TIdEncoderMIME.Create() to create an object instance, you should be using the Encode() instance method instead of the EncodeBytes() static method (which creates another instance internally):

procedure TFormTest.btnTestClick(Sender: TObject);
var
  Encoder: TIdEncoderMIME;
begin
  Encoder := TIdEncoderMIME.Create(nil);
  // prior to Indy 10.6.0, use TIdTextEncoding.Unicode
  // instead of IndyTextEncoding_UTF16LE...
  Edit2.Text := Encoder.Encode(Edit1.Text, IndyTextEncoding_UTF16LE);
  Encoder.Free;
end;

Which can be simplified further using the EncodeString() static method:

procedure TFormTest.btnTestClick(Sender: TObject);
begin
  // prior to Indy 10.6.0, use TIdTextEncoding.Unicode
  // instead of IndyTextEncoding_UTF16LE...
  Edit2.Text := TIdEncoderMIME.EncodeString(Edit1.Text, IndyTextEncoding_UTF16LE);
end;

But either way, the output is all the same. So any problem you are still having has to be elsewhere. But you have not provided any details about how you are validating the data, what tools are rejecting it, what errors are actually being reported, etc.

Sign up to request clarification or add additional context in comments.

16 Comments

thanks for the help , that version of delphi begins to appear "IndyTextEncoding_UTF16LE" ? , because I call the unit IdGlobal but "IndyTextEncoding_UTF16LE" is missing
@MattOlsen it was added in Indy 10.6.0.0 (shipped with XE4), when TIdTextEncoding was replaced with IIdTextEncoding. You can upgrade XE2 to the latest Indy version, or just use TIdTextEncoding.Unicode instead of IndyTextEncoding_UTF16LE .
@RemyLebeau: FreeAndNil, honestly? Encoder will leave scope immediately after that, so there is no need to nil the reference.
@RudyVelthuis it was a copy/paste from the OP's code. On the other hand, by your reaction, should we call Destroy instead of Free to avoid the check for nil, too?
No, we should call Free, and Free only. More about that issue in the Embarcadero forums.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.