Encode/Decode Base64

From ISXKB

Revision as of 17:25, 3 October 2012 by Ath (Talk | contribs)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search

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;
	a := Length(Result) mod 4;
	if a = 2 then
		Result := Result + '=='
	else if a = 3 then
		Result := Result + '=';

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

Personal tools
Ads: