Encode/Decode Base64
From ISXKB
Contents |
Introduction
On a users request I took the liberty of looking up some Pascal code for encoding and decoding data to and from Base64. After a few corrections and modifications it was fit to be compiled by the Inno Setup PascalScript compiler.
The [Code] section
This listing should be added to, or #included in, your [Code] section.
A few notes:
- The actual algorithm is pretty simple, encoding a set of 8 bit databytes to another set of 6 bit databytes (26 == 64, hence 'base 64'), and decoding it back by stuffing all the 6 bit parts back into 8 bit bytes.
- Some standards require extra padding characters, denoted as '=', but that's not (yet) implemented here. The why and how for this padding is explained in the Wiki article (see Web references)
- Because of the nature of the beast, AnsiString is the required parameter- and return-type, to avoid 'complications' when using a Unicode version of Inno Setup.
const Codes64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; function Encode64(S: AnsiString): AnsiString; var i: Integer; a: Integer; x: Integer; b: Integer; begin Result := ''; a := 0; b := 0; for i := 1 to Length(s) do begin x := Ord(s[i]); b := b * 256 + x; a := a + 8; while (a >= 6) do begin a := a - 6; x := b div (1 shl a); b := b mod (1 shl a); Result := Result + copy(Codes64,x + 1,1); end; end; if a > 0 then begin x := b shl (6 - a); Result := Result + copy(Codes64,x + 1,1); end; end; function Decode64(S: AnsiString): AnsiString; var i: Integer; a: Integer; x: Integer; b: Integer; begin Result := ''; a := 0; b := 0; for i := 1 to Length(s) do begin x := Pos(s[i], codes64) - 1; if x >= 0 then begin b := b * 64 + x; a := a + 6; if a >= 8 then begin a := a - 8; x := b shr a; b := b mod (1 shl a); x := x mod 256; Result := Result + chr(x); end; end else Exit; // finish at unknown end; end;
For the not so Pascal-savvy: If you add it toward the end, a few forward declarations may be needed at the beginning of the [Code] section like so:
function Encode64(S: AnsiString): AnsiString; forward; function Decode64(S: AnsiString): AnsiString; forward;
A small test
I tested the basic functionality by creating a very small script, that has this InitializeSetup eventfunction:
function InitializeSetup() : boolean; var s, t : string; begin Result := false; s := '/test /test'; t := 'L3Rlc3QgL3Rlc3QNCg=='; // The expected result MsgBox(Encode64(s) + #13 + Decode64(Encode64(s)) + #13 + Decode64(t),mbInformation,MB_OK); end;
Thorough testing should be performed, but I left that to the original requester, assuming that any errors would be reported to the Inno Setup newsgroups, and fixes could be posted here.
See also
(No references yet)
Web references
- Wikipedia article on Base64
- Original Torry Tips article, (with bugs in the code)
- Online Base64 encoder/decoder used for testing
