Encode string to Base64 in Inno Setup (Unicode Ver

2019-05-30 04:29发布

问题:

Problem

I tried to use the Pascal function EncodeStringBase64, assuming Inno Setup had access to the Pascal standard library but it fails to find it and provides an Unknown Identifier error.

https://www.freepascal.org/docs-html/fcl/base64/encodestringbase64.html

I also found this code to carry out the conversion but it seems to be restricted to AnsiStrings.

https://github.com/docker/toolbox/blob/master/windows/base64.iss

Question

Ideally I'd like to use the standard library function, is there any way that I can access it?

If not, is the code using AnsiStrings safe to use on normal Unicode strings if I change the signature?

I'm going to carry out testing for it, but I'm worried that I'll test a good number of use cases, but this wouldn't guarantee that it's actually suitable for every character, and edge cases may exist.

回答1:

Base64 encodes bytes, not characters (strings). That's also probably the reason, why the Encode64 implementation, that you have found, takes AnsiString. AnsiString is commonly (ab)used in Inno Setup Pascal Script as a dynamic array of bytes. While string is an array of characters.

If you want to encode a string, you first have to represent the string as an array of bytes (in a way the recipient of the Base64-encoded string expects it) and then you can use your Encode64 implementation.

In case you encode ASCII characters only, you can just blindly cast string to AnsiString. If you use non-ascii characters, you will probably want to convert your UnicodeString to bytes using some encoding, like UTF-8.

As for the resulting string, you can just safely cast it from AnsiString to string, as Base64 uses ASCII characters only (though, it also makes sense to change function signature to return string, as it indeed returns a character string, not byte array).

So for an ASCII input, this will do:

Base64 := string(Encode64(AnsiString(S)));

If you want to use a "standard" function, you can use CryptBinaryToString WinAPI function. Though that won't spare you from solving the above, as the function takes an array of bytes on input (as expected).


The above makes a difference only, if you use Unicode Inno Setup (what you correctly do). Had you used Ansi Inno Setup (what you should not), string is AnsiString.