2009. április 30., csütörtök

How to detect if DCOM is enabled


Problem/Question/Abstract:

How to detect if DCOM is enabled

Answer:

function IsDCOMEnabled: Boolean;
var
  Ts: string;
  R: TRegistry;
begin
  r := TRegistry.Create;
  r.RootKey := HKEY_LOCAL_MACHINE;
  r.OpenKey('Software\Microsoft\OLE', False);
  ts := AnsiUpperCase(R.ReadString('EnableDCOM'));
  r.Free;
  Result := (Ts = 'Y');
end;

2009. április 29., szerda

How to send key events to any control in a process


Problem/Question/Abstract:

I want to create a software keyboard in one form. When I press a key on the sofware keyboard, I would like to send the key's char to any form in my application.

Answer:

The following method will send key events to any control in your own process. It will not work reliably for windows in other processes.

{
Procedure PostKeyEx

Parameters:

hWindow:
Target window to be send the keystroke
key:
Virtual keycode of the key to send. For printable keys this is simply the ANSI code (Ord(character)).
shift:
State of the modifier keys. This is a set, so you can set several of these keys (shift, control, alt, mouse buttons) in tandem. The TShiftState type is declared in the Classes Unit.
specialkey:
Normally this should be False. Set it to True to specify a key on the numeric keypad, for example.
If this parameter is true, bit 24 of the lparam for the posted WM_KEY* messages will be set.

Description:

This procedure sets up Windows key state array to correctly reflect the requested pattern of modifier keys and then posts a WM_KEYDOWN/WM_KEYUP message pair to the target window. Then Application.ProcessMessages is called to process the messages before the keyboard state is restored.

Error Conditions:

May fail due to lack of memory for the two key state buffers. Will raise an exception in this case.

Note:

Setting the keyboard state will not work across applications running in different memory spaces on Win32 unless AttachThreadInput is used to connect to the target thread first.

Created:

02/21/96 16:39:00 by Peter Below
}

procedure PostKeyEx(hWindow: HWnd; key: Word; const shift: TShiftState; specialkey:
  Boolean);
type
  TBuffers = array[0..1] of TKeyboardState;
var
  pKeyBuffers: ^TBuffers;
  lparam: LongInt;
begin
  {check if the target window exists}
  if IsWindow(hWindow) then
  begin
    {set local variables to default values}
    pKeyBuffers := nil;
    lparam := MakeLong(0, MapVirtualKey(key, 0));
    {modify lparam if special key requested}
    if specialkey then
      lparam := lparam or $1000000;
    {allocate space for the key state buffers}
    New(pKeyBuffers);
    try
      {Fill buffer 1 with current state so we can later restore it.
                 Null out buffer 0 to get a "no key pressed" state.}
      GetKeyboardState(pKeyBuffers^[1]);
      FillChar(pKeyBuffers^[0], Sizeof(TKeyboardState), 0);
      {set the requested modifier keys to "down" state in the buffer}
      if ssShift in Shift then
        pKeyBuffers^[0][VK_SHIFT] := $80;
      if ssAlt in Shift then
      begin
        {Alt needs special treatment since a bit in lparam needs also be set}
        pKeyBuffers^[0][VK_MENU] := $80;
        lparam := lparam or $20000000;
      end;
      if ssCtrl in Shift then
        pKeyBuffers^[0][VK_CONTROL] := $80;
      if ssLeft in Shift then
        pKeyBuffers^[0][VK_LBUTTON] := $80;
      if ssRight in Shift then
        pKeyBuffers^[0][VK_RBUTTON] := $80;
      if ssMiddle in Shift then
        pKeyBuffers^[0][VK_MBUTTON] := $80;
      {make out new key state array the active key state map}
      SetKeyboardState(pKeyBuffers^[0]);
      {post the key messages}
      if ssAlt in Shift then
      begin
        PostMessage(hWindow, WM_SYSKEYDOWN, key, lparam);
        PostMessage(hWindow, WM_SYSKEYUP, key, lparam or $C0000000);
      end
      else
      begin
        PostMessage(hWindow, WM_KEYDOWN, key, lparam);
        PostMessage(hWindow, WM_KEYUP, key, lparam or $C0000000);
      end;
      {process the messages}
      Application.ProcessMessages;
      {restore the old key state map}
      SetKeyboardState(pKeyBuffers^[1]);
    finally
      {free the memory for the key state buffers}
      if pKeyBuffers < > nil then
        Dispose(pKeyBuffers);
    end;
  end;
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
var
  W: HWnd;
begin
  W := Memo1.Handle;
  PostKeyEx(W, VK_END, [ssCtrl, ssShift], False); {select all}
  PostKeyEx(W, Ord('C'), [ssCtrl], False); {copy to clipboard}
  PostKeyEx(W, Ord('C'), [ssShift], False); {replace with C}
  PostKeyEx(W, VK_RETURN, [], False); {new line}
  PostKeyEx(W, VK_END, [], False); {go to end}
  PostKeyEx(W, Ord('V'), [ssCtrl], False); {paste from keyboard}
end;

2009. április 28., kedd

Disabling the system keys from your application


Problem/Question/Abstract:

When my application is running, I'd like to prevent users from using Ctrl-Alt-Del and Alt- Tab. What's the best way to do this?

Answer:

This is pretty quick one... The best way I've seen yet is to trick Windows into thinking that a screen saver is running. When Windows thinks a screensaver is active, Ctrl-Alt-Del and Alt-Tab (Win95 only for this) are disabled. You can perform this trickery by calling a WinAPI function, SystemParametersInfo. For a more in-depth discussion about what this function does, I encourage you to refer to the online help.

In any case, SystemParametersInfo takes four parameters. Here's its C declaration from the Windows help file:

BOOL SystemParametersInfo(
  UINT uiAction, // system parameter to query or set
  UINT uiParam, // depends on action to be taken
  PVOID pvParam, // depends on action to be taken
  UINT fWinIni // user profile update flag
  );

For our purposes we'll set uiAction to SPI_SCREENSAVERRUNNING, uiParam to 1 or 0 (1 to disable the keys, 0 to re-enable them), pvParam to a "dummy" pointer address, then fWinIni to 0. Pretty straight-forward. Here's what you do:

To disable the keystrokes, write this:

SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, @ptr, 0);

To enable the keystrokes, write this:

SystemParametersInfo(SPI_SCREENSAVERRUNNING, 0, @ptr, 0);

Not much to it, is there? Thanks to the folks on the Borland Forums for providing this information!

2009. április 27., hétfő

Open an application inside a TForm at a predefined position


Problem/Question/Abstract:

How do I open an executable in a determined form's area? Example: Open an executable and show it on the left forms part with a size of 400 x 300.

Answer:

This works for me. Keep in mind that some apps have their startup settings set somewhere which may override the Startup structure you pass.

procedure TForm1.Button1Click(Sender: TObject);
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  FillChar(StartupInfo, Sizeof(StartupInfo), #0);
  StartupInfo.cb := Sizeof(StartupInfo);
  StartupInfo.dwFlags := STARTF_USEPOSITION or STARTF_USESIZE;
  StartupInfo.wShowWindow := SW_SHOWNORMAL;
  StartupInfo.dwX := Left;
  StartupInfo.dwY := Top;
  StartupInfo.dwXSize := 400;
  StartupInfo.dwYSize := 300;
  CreateProcess(nil, 'yourapp.exe', nil, nil, false, CREATE_NEW_CONSOLE or
    NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo);
end;

2009. április 26., vasárnap

How to retrieve all string properties and their values from any TObject descendant


Problem/Question/Abstract:

How to retrieve all string properties and their values from any TObject descendant

Answer:

{ ... }
var
  XObject: TObject;
  XProps: PPropList;
  XPropInfo: PPropInfo;
  XTypeData: PTypeData;
  XPropsStr: string;
  i: integer;
  { ... }
begin
  { ... }
  XObject := OneOfYourComponents;
  XTypeData := TypInfo.GetTypeData(XObject.ClassInfo);
  XPropsStr := '';
  GetMem(XProps, XTypeData^.PropCount * sizeof(Pointer));
  try
    TypInfo.GetPropInfos(XObject.ClassInfo, XProps);
    for i := 0 to XTypeData.PropCount - 1 do
    begin
      XPropInfo := XProps[i];
      if Assigned(XPropInfo) then
      begin
        if XPropInfo.PropType^^.Kind in [tkString, tkLString, tkWString] then
          XPropsStr := XPropsStr + XProps[i].Name + ' = ' +
            GetStrProp(XObject, XProps[i].Name) + #$0D#$0A;
      end;
    end;
  finally
    FreeMem(XProps);
  end;
  ShowMessage(XPropsStr);
  { ... }

2009. április 25., szombat

Maximize the columns of a TStringGrid when the form resizes


Problem/Question/Abstract:

When a form resizes, how do I resize the columns so they will occupy all available space? E.g. if stringgrid.width=100 and I have 4 columns, how do I adjust the columns width?

Answer:

procedure TForm1.FormResize(Sender: TObject);
var
  c: integer;
  colWidth: integer;
  lineWidths: integer;
  delta: integer;
begin
  Grid.Width := ClientWidth - 24; {or whatever}
  lineWidths := Grid.GridLineWidth * (Grid.ColCount - 1);
  colWidth := (Grid.ClientWidth div Grid.ColCount) - Grid.GridLineWidth;
  delta := (Grid.ClientWidth - (colWidth * Grid.ColCount)) - lineWidths;
  for c := 0 to Grid.ColCount - 1 do
  begin
    Grid.ColWidths[c] := colWidth;
    if c = Grid.ColCount - 1 then
      Grid.ColWidths[c] := Grid.ColWidths[c] + delta;
  end;
end;

2009. április 24., péntek

How to respond to QueryNewPalette and PaletteChanged messages


Problem/Question/Abstract:

How to respond to QueryNewPalette and PaletteChanged messages

Answer:

Here is a simple test program I wrote for displaying a 256 color bitmap. It works properly on my system ... so far. The code was derived from a sample which is included in the WM_QUERYNEWPALETTE help description in the Microsoft Visual C++ compiler (The Win API). These examples were not included in the Delphi version of the Win API help file for some reason. Too bad because they are extremely useful.

This code passes all the tests on my system. The app starts with the bitmap displayed correctly. With another app in the foreground or with an icon (for example the MSDOS icon) dragged on top, it displays a proper "background palette". Minimizing and moving the window shows a proper palette.

In the form's Oncreate method, I LoadFromFile to a temp bitmap then StretchDraw that to the Image1 canvas. I found I needed handlers for WM_QueryNewPalette to realize the bitmap's palette - and WM_PaletteChanged to call the WinAPI UpdateColors function to map the palette to the system palette. UpdateColors avoids the horrible background palette map.

unit Paltst;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, ExtCtrls, Menus, Buttons;

type
  TForm1 = class(TForm)
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    procedure QNewPalette(var Msg: TWMQueryNewPalette); message WM_QueryNewPalette;
    procedure PalChanged(var Msg: TWMPaletteChanged); message WM_PaletteChanged;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Bmap: TBitmap;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Word;
begin
  Bmap := TBitmap.Create;
  Bmap.LoadFromFile('Test.bmp');
  Image1.Canvas.StretchDraw(Image1.BoundsRect, Bmap);
end;

procedure TForm1.QNewPalette(var Msg: TWMQueryNewPalette);
var
  i: Word;
  DC: HDC;
  HPold: HPalette;
begin
  DC := Form1.Canvas.Handle;
  HPold := SelectPalette(DC, Bmap.Palette, False);
  i := RealizePalette(DC);
  SelectPalette(DC, HPold, False);
  if (i > 0) then
    InvalidateRect(Handle, nil, False);
  Msg.Result := i;
end;

procedure TForm1.PalChanged(var Msg: TWMPaletteChanged);
var
  i: Word;
  DC: HDC;
  HPold: HPalette;
begin
  if (Msg.PalChg = Handle) then
    Msg.Result := 0
  else
  begin
    DC := Form1.Canvas.Handle;
    HPold := SelectPalette(DC, Bmap.Palette, True);
    i := RealizePalette(DC);
    UpdateColors(DC);
    SelectPalette(DC, HPold, False);
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Bmap.Free;
end;

end.

2009. április 23., csütörtök

Navigate a TPageControl using Ctrl-Tab and Ctrl-Shift-Tab if several pagecontrols are on a form


Problem/Question/Abstract:

I have a PageControl having 3 TabSheets. If this PageControl has a Panel as its parent, then I am able navigate between the tabsheets using Ctrl-Tab (forward) or Shift-Ctrl-Tab (backward) using the keyboard. But if the same pagecontrol has another Tabsheet of a Pagecontrol as its parent, then I am not able to navigate between the tabsheets of the child pagecontrol using the keyboard even though the focus is on the child pagecontrol.

Answer:

Handling proper Ctrl-Tab and Ctrl-Shift-Tab switching of pages if several pagecontrols are on a form:

In form declaration:

procedure CMDialogKey(var msg: TCMDialogKey); message CM_DIALOGKEY;

procedure TForm1.CMDialogKey(var msg: TCMDialogKey);
var
  Control: TWinControl;
begin
  with Msg do
  begin
    if (charcode = VK_TAB) and (GetKeyState(VK_CONTROL) < 0) then
    begin
      Control := ActiveControl;
      while Assigned(Control) do
        if Control is TPageControl then
        begin
          Control.Perform(CM_DIALOGKEY, charcode, keydata);
          Exit;
        end
        else
          Control := Control.Parent;
    end;
  end;
  inherited;
end;

2009. április 22., szerda

Display WYSIWYG fonts in a list box


Problem/Question/Abstract:

You can display the available fonts in a WYSIWYG fashion.

Answer:

Start a new project, add a TListBox, in the Form�s OnCreate event code:

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListBox1.Items := Screen.Fonts;
end;

Set the ListBox�s style property to lbOwnerDrawVariable and finally and the following code to the ListBox�s OnDrawItem and OnMeasureItem events

procedure TForm1.ListBox1MeasureItem(Control: TWinControl; Index: Integer;
  var Height: Integer);
var
  h: integer;
begin
  with Control as TListBox do
  begin
    Canvas.Font.Name := Items[Index];
    h := Canvas.TextHeight(Items[Index]);
  end;
  Height := h;
end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
  Rect: TRect; State: TOwnerDrawState);
begin
  with Control as TListBox do
  begin
    Canvas.Font.Name := Items[Index];
    Canvas.FillRect(Rect);
    Canvas.TextOut(Rect.Left, Rect.Top, Items[Index]);
  end;
end;

2009. április 21., kedd

Changing system date and time in Windows


Problem/Question/Abstract:

I want to assign a new time to the system time. How would I do this? I tried to get the system time through GetSystemTime() and set the new time to SetSystemTime(), but I get the wrong results.

Answer:

Solve 1:

This sets the time to the same time in year 1999:

procedure TForm1.Set1999(Sender: TObject);
var
  stSystemTime: TSystemTime;
begin
  Windows.GetLocalTime(stSystemTime);
  stSystemTime.wYear := 1999;
  Windows.SetLocalTime(stSystemTime);
end;


Solve 2:

By using the following call (example is a method of a button click) you may directly modify the date and time of Windows.

procedure TForm1.Button1Click(Sender: TObject);
var
  NewTime: TSystemTime;
begin
  FillChar(NewTime, sizeof(NewTime), #0);
  NewTime.wYear := 2000;
  NewTime.wMonth := 8;
  NewTime.wDay := 28;
  NewTime.wHour := 0;
  NewTime.wMinute := 0;
  NewTime.wSecond := 0;
  NewTime.wMilliseconds := 0;

  SetLocalTime(NewTime);
end;

Please note that when you do chage the system time, send a WM_TIMECHANGE message to all toplevel windows so that they can detect the time change...  You should do this for all version of windows but 2000 since it does it by its self.  Bellow is the code:

if IsWin2000 = False then
  SendMessage(HWND_TOPMOST, WM_TIMECHANGE, 0, 0);

function IsWin2000(): Boolean;
var
  OSInfo: TOSVersionInfo;
begin
  Result := False;
  OSInfo.dwOSVersionInfoSize := SizeOf(OsInfo);
  if not GetVersionEx(OSInfo) then
  begin
    Exit;
  end;
  if OsInfo.dwPlatformID = VER_PLATFORM_WIN32_NT then
  begin
    if OSInfo.dwMajorVersion >= 5 then
      Result := True;
  end;
end;

2009. április 20., hétfő

Scroll text in title bar of a window


Problem/Question/Abstract:

How to scroll a string of text in the caption of a window, in an editbox or in the application''s title so it''s displayed in the Start-menu toolbar (even when the form is minimized).

Answer:

It's very simple to scroll a text so it gets displayed in the Start-menu toolbar the same way as Winamp scrolls a songs title.

First two global variables are needed:

var
  ScrollPosition: integer = 0;
  ScrollText: string = '     This is the scrolltext...';

The first integer ScrollPosition keep tracks of the current position of the scroll text, and the string ScrollText is the actual text that will scroll. A tip is to start the scroll text with the same number of spaces as the number of characters that will be displayed at the same time, then the scroll will seem to start from the right and scroll to the left instead of the first character popping up directly at the first position.

The procedure that does the actual scrolling needs to be called every time the scroll needs to be updated. An OnTimer event (TTimer) suits good for that matter.

procedure TForm1.Timer1Timer(Sender: TObject);
const
  SCROLL_AREA = 10;
begin
  // Gets the part of the scroll that should be displayed
  Form1.Caption := Copy(ScrollText, ScrollPosition, SCROLL_AREA);

  // Increase scroll position to the next character
  Inc(ScrollPosition);

  // Reset position when the scroll has reached it's end
  if ScrollPosition >= Length(ScrollText) then
    ScrollPosition := 0;
end;

The code is pretty self explaining together with it's comments. The constant SCROLL_AREA decides how many characters of the scroll should be displayed at once.

Exactly the same code may be used to scroll text in an TEdit control instead, simply replace Form1.Caption with Edit1.Text (or what the name of the control is) instead. To make the title of the window that is viewed in the Start-menu toolbar to scroll, use Application.Title.

2009. április 19., vasárnap

Working with Browser


Problem/Question/Abstract:

Execute a Javascript function in a Webbrowser/ IE Document?

Answer:

uses
  MSHTML_TLB, SHDocVw, ShellAPI;

function to execute a script function

function ExecuteScript(doc: IHTMLDocument2; script: string; language: string):
  Boolean;
var
  win: IHTMLWindow2;
  Olelanguage: Olevariant;
begin
  if doc <> nil then
  begin
    try
      win := doc.parentWindow;
      if win <> nil then
      begin
        try
          Olelanguage := language;
          win.ExecScript(script, Olelanguage);
        finally
          win := nil;
        end;
      end;
    finally
      doc := nil;
    end;
  end;
end;

Examples how to login to gmx homepage

procedure FillInGMXForms(WB: ShDocVW_TLB.IWebbrowser2; IDoc1: IHTMLDocument2;
  Document: Variant; AKennung, APasswort: string);
const
  IEFields: array[1..4] of string = ('INPUT', 'text', 'INPUT', 'password');
var
  IEFieldsCounter: Integer;
  i: Integer;
  m: Integer;
  ovElements: OleVariant;
begin
  if Pos('GMX - Homepage', Document.Title) <> 0 then

    while WB.ReadyState <> READYSTATE_COMPLETE do
      Application.ProcessMessages;

  // count forms on document and iterate through its forms
  IEFieldsCounter := 0;
  for m := 0 to Document.forms.Length - 1 do
  begin
    ovElements := Document.forms.Item(m).elements;

    // iterate through elements
    for i := ovElements.Length - 1 downto 0 do
    begin
      try
        // if input fields found, try to fill them out
        if (ovElements.item(i).tagName = IEFields[1]) and
          (ovElements.item(i).type = IEFields[2]) then
        begin
          ovElements.item(i).Value := AKennung;
          Inc(IEFieldsCounter);
        end;

        if (ovElements.item(i).tagName = IEFields[3]) and
          (ovElements.item(i).type = IEFields[4]) then
        begin
          ovElements.item(i).Value := APasswort;
          Inc(IEFieldsCounter);
        end;
      except
        // failed...
      end;
    end; { for i...}
  end; { for m }
  // if the fields are filled in, submit.
  if IEFieldsCounter = 3 then
    ExecuteScript(iDoc1, 'document.login.submit()',
      'JavaScript');
end;

function LoginGMX_IE(AKennung, APasswort: string): Boolean;
var
  ShellWindow: IShellWindows;
  WB: ShDocVW_TLB.IWebbrowser2;
  spDisp: IDispatch;
  IDoc1: IHTMLDocument2;
  Document: Variant;
  k: Integer;
begin
  ShellWindow := CoShellWindows.Create;
  // get the running instance of Internet Explorer
  for k := 0 to ShellWindow.Count do
  begin
    spDisp := ShellWindow.Item(k);
    if spDisp = nil then
      Continue;
    // QueryInterface determines if an interface can be used with an object
    spDisp.QueryInterface(iWebBrowser2, WB);
    if WB <> nil then
    begin
      WB.Document.QueryInterface(IHTMLDocument2, iDoc1);
      if iDoc1 <> nil then
      begin
        WB := ShellWindow.Item(k) as ShDocVW_TLB.IWebbrowser2;
        Document := WB.Document;
        // if GMX page...
        FillInGMXForms(WB, IDoc1, Document, AKennung, APasswort);
      end; { idoc <> nil }
    end; { wb <> nil }
  end; { for k }
end;

Navigate to the gmx homepage in the IE browser an login

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShellExecute(Handle,
    'open',
    'http://www.gmx.ch',
    nil,
    nil,
    SW_SHOW);
  Sleep(2000);
  LoginGMX_IE('user@gmx.net', 'pswd');
end;

Navigate to the gmx homepage in the Webbrowser an login

procedure TForm1.Button2Click(Sender: TObject);
var
  IDoc1: IHTMLDocument2;
  Web: ShDocVW_TLB.IWebBrowser2;
begin
  Webbrowser1.Navigate('http://www.gmx.ch');
  while Webbrowser1.ReadyState <> READYSTATE_COMPLETE do
    Application.ProcessMessages;
  Webbrowser1.Document.QueryInterface(IHTMLDocument2, iDoc1);
  Web := WebBrowser1.ControlInterface;
  FillInGMXForms(Web, iDoc1, Webbrowser1.Document, 'user@gmx.net', 'pswd');
end;

2009. április 18., szombat

Abbreviating Array Properties


Problem/Question/Abstract:

Wouldn't it be much easier to enter AStringList[Index] instead of AStringList.Strings[Index]? Well you can, and you can add this functionality to your own classes.

Answer:

This may be obvious to some, but it's also something that I haven't come across until now, so I figured it might be useful to someone out there.

For many array properties found in classes in delphi, you can simplify access by abbreviating the call.  This means that you can use the syntax ArrayProperty[Index] as opposed to ArrayProperty.Items[Index].

Either way is appropriate, and there is no right or wrong, however here is what I think.  The advantage to using the abbreviated version make repeated calls easier to look at, especially if there are in one parameter list.  The only disadvantage I can think of is that someone else reading the code might not be able to determine what you are referencing without some thought, or knowledge of the class in question.

Here's an example using a TStringList:

Unabbreviated:

for I := 0 to MyStringList.Count - 1 do
  ShowMessage(MyStringList.Strings[I]);

Abbreviated:

for I := 0 to MyStringList.Count - 1 do
  ShowMessage(MyStringList[I]);

Again, in that example it really doesn't save much, but in my code I have some classes I created and have to repeatedly call different sometimes.  Here's an example of something I might do, and how the abbreviation cleans things up:

for I := 0 to UserList.Count - 1 do
  if AUser.Read(UserList.Items[I].Company, UserList.Items[I].User) then
  begin
    ACompanyStr := UserList.Items[I].Company;
    AUserStr := UserList.Items[I].User;
  end;

Now the code in this example is pretty useless, and some would say why not use a 'with UserList.Items[I] do' statement to clean things up.  However often I might have these nested within other 'with' statments, so the 'with' solution is not available.

Now look at the abbreviated code:

for I := 0 to UserList.Count - 1 do
  if AUser.Read(UserList[I].Company, UserList[I].User) then
  begin
    ACompanyStr := UserList[I].Company;
    AUserStr := UserList[I].User;
  end;

It definetly reduces the amount of code, and I believe it does clean up the appearance.  

What makes this all possible is the use of the 'default' directive with the corresponding array property.  

This can be used for many different items in delphi already including TStringList, TListItem, etc. but there are some items that do not have default array properties and therefore you cannot access in the abbreviated fashion.

If you attempt to access something that does not have the default array property, such as the TListView component (I.E. ListView[I].Caption instead of ListView.Items[I].Caption), you will recieve an error such as "Class does not have default property".

2009. április 17., péntek

Debug a Delphi Expert instaled as a package


Problem/Question/Abstract:

Debugging an Expert can be a tedious task, unless you follow these steps.

Answer:

Ok, here are the instructions.

Open your package.

You have toModify the Project Options: In the Packages tab uncheck your package. In the Compiler tab uncheck Optimization, select the Stack_frames option, an select also the debugger options.

Compile the package.

Select Run-Parameters, select Delphi as the host application, (a package is just a DLL with a fancy extension). Click the Load Button.

Press F9, another instance of Delphi will load, so run your expert from there.

Now you can use the debugger from the first instance of Delphi to debug your expert code running in the second one.

2009. április 16., csütörtök

Drag and Drop Thread


Problem/Question/Abstract:

This demo shows how to perform a drag drop wich does not block the user interface during the copying of large files.

Answer:

{ Drag & Drop Thread
  Copyright (c) 2000, 2001 by E.J.Molendijk

  This class is a part of:
  "Drag and Drop Component Suite" (http://www.melander.dk).

  Explained:
  When you create the thread, it will copy the filenames of the specified
  DropFileSource. These filenames will be used by thread to perform a
  drag&drop operation. The calling thread continues uninterupted.

  Usage is very simple:
    TDragDropThread.Create(DropFileSource1);

  Drag&Drop Thread info Q139408:
    http://support.microsoft.com/support/kb/articles/Q139/4/08.asp
}

unit DragDropThread;

interface

uses
  Classes, DropSource, ActiveX, Windows;

type
  TDragDropThread = class(TThread)
  private
    { Private declarations }
    FFiles: string;
  protected
    procedure Execute; override;
  public
    constructor Create(DropFileSource: TDropFileSource);
  end;

implementation

{ TDragDropThread }

constructor TDragDropThread.Create(DropFileSource: TDropFileSource);
begin
  // Thread will start immediately after creation
  inherited Create(False);

  // Copy filenames from supplied DropFileSource
  FFiles := DropFileSource.Files.Text;

  // This thread disappeard when it finishes
  FreeOnTerminate := True;
end;

procedure TDragDropThread.Execute;
var
  DropFileSource: TDropFileSource;
  pt: TPoint;
  hwndAttach: HWND;
  dwAttachThreadID, dwCurrentThreadID: DWORD;

begin
  // Get handle of window under mouse-cursor
  GetCursorPos(pt);
  hwndAttach := WindowFromPoint(pt);
  Assert(hwndAttach <> 0, 'Unable to find window with drag-object');

  // Get thread ID's
  dwAttachThreadID := GetWindowThreadProcessId(hwndAttach, nil);
  dwCurrentThreadID := GetCurrentThreadId();

  // Attach input queues if necessary
  if (dwAttachThreadID <> dwCurrentThreadID) then
    AttachThreadInput(dwAttachThreadID, dwCurrentThreadID, True);

  // Initialize Ole for this thread
  OleInitialize(nil);
  try
    // create dropsource
    DropFileSource := TDropFileSource.Create(nil);
    try
      DropFileSource.Files.Text := FFiles;
      // start drag&drop
      DropFileSource.Execute;
    finally
      // cleanup dropsource
      DropFilesource.Free;
    end;
  finally
    // cleanup Ole
    OleUninitialize;
  end;
  // Restore input queues settings
  if (dwAttachThreadID <> dwCurrentThreadID) then
    AttachThreadInput(dwAttachThreadID, dwCurrentThreadID, False);
end;

end.

2009. április 15., szerda

Block mouse clicks to a specific window

Problem/Question/Abstract:

I need to create an invisible window over a webbrowser component so that I can stop mouse clicks.

Answer:

There are much better ways to block mouse clicks to a specific window. You can use a handler for the Application.OnMessage event, for example:

procedure TMainform.FormCreate(Sender: TObject);
begin
Application.OnMessage := AppOnMessage;
end;

procedure TMainform.AppOnMessage(var Msg: TMsg; var Handled: Boolean);
begin
case Msg.Message of
WM_MOUSEFIRST..WM_MOUSELAST, WM_MOUSEWHEEL:
if Msg.hwnd = Webbrowser1.HWND then
Handled := True;
end;
end;


2009. április 14., kedd

Secure Compression for TStringList

Problem/Question/Abstract:

How to load and save encrypted string lists

Answer:

I combined routines from two open source projects to produce a simple way of saving a stringlist to disk in a compressed and very securely encrypted fashion (using the AES algorithm).

The two components are LockBox from Turbopower - available at
http://sourceforge.net/projects/tplockbox/ http://sourceforge.net/projects/tplockbox/
and UCL Compression Library API for Borland Delphi from
http://www.zeitungsjunge.de/delphi/ucl/index.htm http://www.zeitungsjunge.de/delphi/ucl/index.htm

The unit EncCompress is listed below. It defines a simple class TCompEnc which lets you load a text file into the stringlist. To save a plain text string list, first compress it using the UCLCompressStream, then feed this into the lockbox encryption component and save that to disk. Loading the encrypted file back in is just a matter of reversing the process, load the file, decrypt it then decompress it.

I've provided a simple test program - just drop a couple of buttons onto a form and hook up the click event to these routines. Make sure that the text for the key is the same in both!! You'll need a test  file 'test.txt', and after clicking both buttons you should find that the 'test2.txt' that is output is identical to the original.

I appreciate I've done two things which aren't very good- one use an internal member directly (enc.flist) and used a tMemoryStream to save and load files from disk instead of a TFileStream (before anyone points these out!)

Note: the AES (Rijndael) is symmetric so the same key encrypts and decrypts.

// Sample event handler code

procedure TForm1.Button1Click(Sender: TObject);
var
enc: TCompEnc;
list: tstringlist;
begin
Enc := TCompEnc.Create;
list := tstringlist.create;
list.LoadFromFile('test.txt');
enc.flist.Text := list.text;
enc.KeyText := 'hgjhgkjghkjh654328878';
enc.SaveToFile('test.dat');
enc.free;
list.free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
enc: TCompEnc;
begin
Enc := TCompEnc.Create;
Enc.KeyText := 'hgjhgkjghkjh654328878';
Enc.LoadFromfile('test.dat');
Enc.Flist.SaveToFile('test2.txt');
Enc.free;
end;

// The unit
unit EncCompress;

interface

uses
Windows, SysUtils, Classes, diuclstreams, LbCipher, LbClass;

type
TCompEnc = class
FList: TStringList;
FKeyText: string;
private
function GetList: TStringlist;
procedure SetKeyText(const Value: string);

public
constructor Create;
destructor Destroy; override;
procedure LoadFromFile(Filename: string);
procedure SaveToFile(Filename: string);
property List: TStringlist read GetList;
property KeyText: string write SetKeyText;
end;

implementation

uses math;

const
COMPRESSION_LEVEL = 3;
BUFFER_SIZE = $4000;

{ TCompEnc }

constructor TCompEnc.Create;
begin
inherited;
Flist := TStringList.Create;
end;

destructor TCompEnc.Destroy;
begin
FList.Free;
inherited;
end;

function TCompEnc.GetList: TStringlist;
begin
Result := Flist;
end;

// Step 1 Compress Flist Strings into stream
// Compress stream
// Save stream to file.

procedure TCompEnc.SaveToFile(Filename: string);
var
Str: TStringStream;
CompStream: TMemoryStream;
FileStream: TMemoryStream;
MyCipher: TLbRijndael;
begin
MyCipher := TLbRijnDael.Create(nil);
MyCipher.GenerateKey(FKeyText);

Str := tStringStream.Create(Flist.Text);
Str.Position := 0;
CompStream := TMemoryStream.create;
UclCompressStream(Str, CompStream, 3, BUFFER_SIZE);
Str.Free;
CompStream.Position := 0;
try
// Prepare key...
Filestream := tmemoryStream.Create;
MyCipher.EncryptStream(CompStream, FileStream);
FileStream.Position := 0;
FileStream.SaveToFile(Filename);
FileStream.Free;
finally
CompStream.Free;
end;
end;

// Loads File.
// 1st step, decrypt from AES to just Compressed
// 2nd step, Decompress into flist

procedure TCompEnc.LoadFromFile(Filename: string);
var
Source, Dest: TMemoryStream;
MyCipher: TLbRijnDael;
begin
// Decryption
Source := TMemoryStream.Create;
Source.LoadFromFile(Filename);
Source.Position := 0;
Dest := TMemoryStream.Create;
MyCipher := TLbRijnDael.Create(nil);
MyCipher.GenerateKey(FKeyText);

try
MyCipher.DecryptStream(Source, Dest);
MyCipher.Free;
Dest.Position := 0;
Source.Position := 0;

if UclDecompressStream(Dest, Source, BUFFER_SIZE) then
begin
Flist.Clear;
Source.Position := 0;
Flist.LoadFromStream(Source);
end;
finally
Dest.Free;
end;
Source.Free;
end;

procedure TCompEnc.SetKeyText(const Value: string);
begin
FKeyText := Value;
end;

end.


2009. április 13., hétfő

Easy Parsing an XML File

Problem/Question/Abstract:

In modern times, a configuration file has to be an XML standard so you want to parse that file to get the elements from corresponding nodes.

Answer:

First you have to import the Type library. This will create a wrapper class for that component and all you have to do is to name it in uses in your unit.
I used msxml.dll(Version 2.0) to install the XML parsing components in the IDE through the Import Type Library option.

See article for more details: Importing XML DOM Parser in Delphi

Second we produce a simple XML file like a configuration file:
(Name the file myconfig.xml)

<?xml version="1.0"?>
<databases>
<database db="InterBase">
<connection>
<name>TrueSoft</name>
<path>superPath</path>
<user>MaxMin</user>
</connection>
</database>
<database db="myMax">
<connection>
<name>maXml</name>
<server>kylix02</server>
<user>carpeDiem</user>
</connection>
</database>
</databases>

Third we build the procedure that parses 3 elements and assign it to strings:

myname, mypath, myuser: string[255];

The accID and idNr are just to make the procedure more flexible for permissions and node navigation. The whole procedure goes like this:

Find the file myconfig.xml
Create the interface pointer xmlDoc
Load the XML file
Check the error handling with xmlDoc.parseError
Select the node
Check if it has childs
Get the nodelist and assign the elements to strings


procedure TForm1.parseXML;
var
SRec1: TSearchRec;
accID: boolean;
idNr: byte;
myXMLpath: string;
xmlDoc: IXMLDomDocument2;
xmlnode: IXMLDomNode;
xmlnodelist: IXMLDomNodeList;
myname, mypath, myuser: string[255];
begin
accID := true;
idNr := 1;
myXMLpath := extractFilePath(Application.ExeName);
if FindFirst(myXMLpath + 'myconfig.xml', faAnyFile, SRec1) = 0 then
begin
xmlDoc := CoDomDocument30.Create;
xmlDoc.validateOnParse := True;
xmlDoc.async := False;
xmlDoc.load(myXMLpath + 'myconfig.xml');
if xmlDoc.parseError.errorCode = 0 then
begin
if accID then
begin
xmlDoc.setProperty('SelectionLanguage', 'XPath');
xmlnode := xmlDoc.selectSingleNode('//databases/database
[@db = '+''''+' InterBase '+''''+ ']');
if xmlnode.hasChildNodes then
begin
if (idNR <= xmlnode.childNodes.length) and (idNR > 0) then
begin
xmlnodelist := xmlnode.childNodes.item[(idNR - 1)].selectNodes
('name');
if xmlnodelist.length <> 0 then
myname := xmlnode.childNodes.item[(idNR - 1)].selectNodes('name').item
[0].text;
xmlnodelist := xmlnode.childNodes.item[(idNR - 1)].selectNodes
('path');
if xmlnodelist.length <> 0 then
mypath := xmlnode.childNodes.item[(idNR - 1)].selectNodes('path').item
[0].text;
xmlnodelist := xmlnode.childNodes.item[(idNR - 1)].selectNodes
('user');
if xmlnodelist.length <> 0 then
myuser := xmlnode.childNodes.item[(idNR - 1)].selectNodes('user').item
[0].text;
end;
end
else
showmessage('no XML Childs');
end
else
showmessage('no permission');
end
else
begin
showmessage('load XML error');
xmlDoc := nil;
FindClose(SRec1)
end;
end
else
showmessage('no XML file');
end;


2009. április 12., vasárnap

Insert Zero converted number to text

Problem/Question/Abstract:

When I convert number(0012) to text I take a result just number (12). How can i take a result of number with zeros?

Answer:

Solve 1:

function StrZero(AValue, ALength: integer): string;
begin
Result := FormatFloat(StringOfChar('0', ALength), AValue);
end;


Solve 2:

function FormatWithZero(const AValue, ALen: Integer): string;
begin
Result := Format('%.' + IntToStr(ALen) + 'd', [AValue]);
end;


2009. április 11., szombat

Bravion - Strong Encryption Algorithm


Problem/Question/Abstract:

Is there more to encryption than XORing output from Random(256) with a chars from a string? Yes there's allot more to it.

Answer:

ABOUT

The name Bravion is pronnounced brave-ion. It is an alegory for molecules undergoing chemical reactions. A molecule is separeted into its ions, which then regroup with ions from a reactant to form new ions. In this algorithm, the ions change properties as well: protons, neutrons and electrons are reconfigured by the reactant and make the resulting molecules unpredictable without knowing the original reactant. Indeed it takes a brave ion to undergo such abuse :)

The routines here aren't very straight forward, even for one who has studied ciphers. I will try to keep it in lamens terms to the best of my ability. Bravion uses a 256bit key and a 128bit block size. It is an iterated (multiple rounds) substitution/permutation network. It is fast, but not nearly the fastest I've seen. I encrypt around 3MB/sec on my system.

GLOSSARY - read carefully

block size:
Size in bits of the data to encrypt (fixed in all block ciphers)

plaintext:
Data that has not yet been encrypted.

ciphertext:
Data that has been encrypted.

key:
Data used to modify plaintext into an incomprehensible sate.

entropy:
Unpredicatble data.

permutation:
Transformation of data by displacements (of individual or grouped bits) or transformation of data by mathematical    functions. Dependent permutations require another source of data, and once permutated, both data are required to    reverse the permutation.

dependency:
Data required to inverse a permutation.

key size:
Size in bits of the data used as a key (this can be  variable in *some* ciphers, but is limited to the dependency imposed by the block size)

xor:
Bitwise exclusive OR. xor has an important property:  if A xor B = C, then C xor A = B, C xor B = A  xor works wonders for permutations.

mul:
Multiplication modulo 2^32 where a factor of 0 is  interpreted as 2^32+1.

add:
Addition modulo 2^32.

sub:
Subtraction modulo 2^32.

shr:
Bit-shift to the right covering the ENTIRE block of data rather than individual integers.

shl:
Same as shr, but the bit shift is to the left.

substitution:
Exchanging one group of bits for another. The result of a substitution depends on the bits that are being substituted.  This process is always reversable, using irreversable substitution to change data is considered  (by myself) a  permutation.

S-BOX:
An array of values that are used to replace on block of  data for another such as SBOX:array[0..255]of byte would    be used to replace a byte for another:

B: byte;
B := SBOX[B];

To reverse the process S-BOXs can be structured such that  SBOX[SBOX[B]]=B or (preferably) a compliment of the X-BOX  can be created such that SBOX_1[SBOX_0[B]]=B  An S-BOX's array must be of suitable size to accept any  input data as an index (for a byte: 0..255, for a word:  0..65535). S-BOXs are very efficient substitution
mechanisms.

feistel network:
Data is divided into 2 halfs, one half is permutated  (and/or substituted) and the second half is a product  (usualy an xor) of the permuted first half and  itself. To reverse the process the inverse of the  product is obtained for to restore the second half  (in the case of an xor, another xor does the trick)  and the first half is then restored with the inserve    of the permutation applied to it.

round:
An intteration of a set of functions. Almost all ciphers  implement rounds. Some use as little as 8, others use as    many as 32. A general rule of thumb is the more rounds,  the harder it is to break the cipher (unless the rounds    are very simple). The number of rounds is usualy a little  bigger than the minimum needed to maintain a safe cihper.  It is a compromise between security and speed.

round keys:
Data that contains entropy from the key used in sequencial  order determined by the current round.

component:
A group of operations (permutations, substitutions etc..)

attacker:
Someone trying to decrypt ciphertext without the key.

satistical analysis:
Using probability theory to aid in *guessing* possible  plaintext from ciphertext.

brute force:
Decrypting ciphertext with every possible key until the  plaintext is found. If an attacker is unable to break a  cipher, the only option is brute force (holding a gun to  whomever knows the key's head is not considered brute  force, it's considered social engineering)

ALGORITHM

The encryption process can be broken down into 5 components.

BEFORE ITTERATING THROUGH THE ROUNDS

[1]

B[0] := B[0] xor RK[PK[16], 0]; //PK holds the path keys
B[1] := B[1] xor RK[PK[17], 1]; //that determine the round
B[2] := B[2] xor RK[PK[18], 2]; //keys to use
B[3] := B[3] xor RK[PK[19], 3];

A key-dependent permutation by XOR with round keys. Which round keys are used depends on the original key. A set of  path keys is extrapolated from the key. Which round keys  are used is unknown to an attacker. This is done so that   in the event that portions of the round keys have been  recovered by an attacker, knowledge of the original key   is inherently required. The original key cannot be found by solving all the round keys due to the initialization     mechanism (discussed later). This is done to the plaintext before entering the first round and after finishing the  last round. This dissolves linearity of repetited components (even though there should be none, I have taken no chances with Bravion. I have not seen this sort of  permutation in any other algorithm, but I am confident that this component seriously impairs an attacker's chances at successful statistical analysis.

ROUND DESCRIPTION

This part is repeated 16 times.

[2]

CarryBit := (B[0] and 2147483648) shr 31;
B[0] := (B[0] shl 1) or ((B[1] and 2147483648) shr 31);
B[1] := (B[1] shl 1) or ((B[2] and 2147483648) shr 31);
B[2] := (B[2] shl 1) or ((B[3] and 2147483648) shr 31);
B[3] := (B[3] shl 1) or CarryBit;

the data put through a shl and the last bit of the block is put into the first bit. In most ciphers data is only re-ordered in bytes, word, or longwords, and this leads to statistical analysis of these groups of bits. Since each bit is shifted 1 bit, every byte/word/longword recieves 1 bit from the previous. After itterating through 16 rounds, each byte has been permuted with each bit twice. Their order does not change however, so the same statistical analysis can be accomplished. The solution to this problem lies in [4]. The reverse is a shr and the first bit of the block is put into the last bit.

[3]

B[3] := B[3] xor (B[2] - RK[i, 3]);
B[2] := B[2] xor Mul(B[1], RK[i, 2]);
B[1] := B[1] xor (B[0] + RK[i, 1]);
B[0] := B[0] xor RK[i, 0];

Taking out all the components designed to reinforce Bravion except [5], the heart of Bravion lies here. The Theory employed here lies in 3 algebraic [is that how it's spelt?] groups, add, mul, xor each having an etropy the same size as its inputs (in this case 32bits). Using a fixed parameter (the round key) and going through each possible value with the second parameter will never result in the same output with any of these 3 groups. The second important property of this component is that all but one longword of the block are dependent of the others. To solve B[1] you must solve B[0], to solve B[2] you have to have solved B[2] with B[0] and so on. Only B[0] is independent of the other longwords of the block. xor is used, because of the inefficiency (in speed) of calculating the inverses of these algebraic groups.

[4]

for i := 0 to 15 do
  T[i] := B[P0[PK[i], 0]]
    Move(T, B, 16);
//T,B:array[0..15]of byte    

This is what I called a re-ordering matrix. Things get a little akward in this component. Have a look at the square     matrix below:

P0: array[0..15, 0..15] of longword = (
  ($A, $3, $B, $C, $5, $E, $9, $F, $0, $7, $4, $6, $1, $D, $2, $8),
  ($9, $5, $F, $3, $1, $0, $A, $4, $7, $B, $E, $8, $2, $6, $D, $C),
  ($6, $D, $A, $4, $3, $5, $2, $8, $B, $F, $9, $C, $0, $E, $7, $1),
  ($E, $7, $0, $D, $8, $B, $1, $3, $9, $6, $C, $4, $A, $2, $F, $5),
  ($C, $A, $2, $5, $F, $D, $7, $9, $4, $E, $6, $B, $8, $3, $1, $0),
  ($5, $9, $3, $8, $D, $6, $4, $C, $1, $0, $7, $2, $E, $B, $A, $F),
  ($0, $6, $4, $A, $7, $3, $B, $E, $2, $8, $5, $1, $D, $F, $C, $9),
  ($D, $F, $9, $0, $6, $2, $3, $1, $E, $C, $A, $5, $B, $8, $4, $7),
  ($1, $0, $C, $2, $9, $7, $6, $D, $3, $5, $8, $E, $F, $A, $B, $4),
  ($3, $8, $5, $7, $2, $C, $E, $B, $A, $9, $D, $F, $4, $1, $0, $6),
  ($F, $B, $D, $1, $C, $8, $0, $6, $5, $2, $3, $7, $9, $4, $E, $A),
  ($8, $E, $1, $9, $4, $F, $C, $5, $6, $D, $2, $A, $7, $0, $3, $B),
  ($4, $C, $7, $6, $E, $1, $5, $2, $F, $A, $B, $0, $3, $9, $8, $D),
  ($7, $2, $6, $B, $0, $4, $D, $A, $8, $1, $F, $3, $5, $C, $9, $E),
  ($2, $1, $8, $E, $B, $A, $F, $7, $D, $4, $0, $9, $C, $5, $6, $3),
  ($B, $4, $E, $F, $A, $9, $8, $0, $C, $3, $1, $D, $6, $7, $5, $2));

Pay attention to the values in each rown and each column. In every row, values from 0 to 15 are assigned once, and in every column, values from 0 to 15 are assigned once. Each row represents an order to put the bytes of the block in. To demonstrate I will use the following block of plaintext:

B = 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31

Using the first row for this demonstration value can be assigned to a temporary block through indexing:

T[0] := B[P0[0]]; //T[0]:=B[$A];
T[1] := B[P0[1]]; //T[1]:=B[$3];
T[2] := B[P0[2]]; //T[2]:=B[$B];
{...and so on... }
T[15] := B[P0[15]]; //T[15]:=B[$8];

T = 26, 19, 27, 28, 21, 30, 25, 31, 16, 23, 20, 22, 17, 29, 18, 24
    
T now contains all bytes of B, but in the new order. T is then copied into B and B has been re-ordered. There are 16  rows in all. A path key determines which row to use, hence which order to put B in. To reverse the permutation I have created a re-ordering matrix that is the inverse of this one such that T[0]=B[P0[0]], B[0]=T[P1[0]. There are 16! (=~2.09x10^13=~2^44) ways to re-order 16 bytes. This subsitution occurs 16 times, and since no 2 rows will put     any byte in the same position (look at the columns), the number of possible orders is increased by a factor of 16     each time, for a total of 16^16. This means that we cover all the possible orders 4.2 million times in excess! This is only the theoretical boundary, the true boundary is  still 16!, but we at least know that the resulting ciphertext could be in ANY of these 16! arrangements. The re-ordering matrix by itself helps, but does not do much against statistical analysis because the bits are still in 8bit groups. Combined with the re-ordering matrix, the 1bit shift, scatters bits independently from each-other in 16! orders. I have read papers stating that idealy, blocks should be permuted as one block and not sub-blocks, but  that because of the data size required to achieve such a large permutation would be beyond the reach of our technology. To put things into context, an S-BOX of 8bits in 8bits out is 255bytes, 16bits-in 16bits-out is 131072bytes, 128bits-in 128bits-out would be 5.4x10^39bytes! Unfortunatly, this structure only allows for 2^44 different block-sized permutations, but it's still a great advantage.

[5]

for i := 0 to 15 B[i] := S0[B[i], j];
//B:array[0..15]of byte

This component substitutes each byte in B for another. There are 16 of these S-BOXs and an inversed S-BOX for     each. One S-BOX is used for each round. I've added these S-BOXs as a precaution. I used my random number generator NoiseSpunge (article name "Cryptographic Random Numbers") to generate completly random S-BOXs. The result is the outputs are drastic permutations on 8bit groups.

INITIALIZATION

Initialization is done in 3 steps.

[1]

The key is divided into 32 bit groups. Each group serves as as seed to a pseudo random number generator (PRNG). This PRNG has a period of 2^32 implying that no 2 seeds will generate the same sequence and that it will no show signs of a pattern before ~4billion numbers have been output. Each of the 8 seeds are used to generate 256bits which are stored as the round keys.

[2]

Path keys are extrapolated directly from the key by means of this function:

for i := 0 to 15 do //SET 4BIT PATH KEYS
begin
  PK[i] := (Key[i] xor Key[i + 16]) and $F;
  j := 16 + (i mod 8);
  PK[j] := PK[j] xor (Key[i] xor Key[i + 16]) and $F0) shr 4;
end; //Key is interpreted as array[0..31]of byte

[3]

The key is encrypted with the current round keys and the resulting ciphertext is used to replace 2 sets of round     keys. This is repeated until each set of round keys has been overwritten 128 times. This may seem like obsessive     paranoya, but that would be incorrect. This is a precaution against brute force. If initialization requires encrypting     256 blocks, then for every key an attacker wants to test  will take the a little longer than it takes to decrypt 256     blocks! Of course to the end user this doesn't even put a dent in his processor usage, but to an attacker trying to     test 2^256 keys, it will lengthen his search by a factor of 256. This is like adding 8bits of key data to his search. I haven't seen this form of initialization used as a brute force deterent before, but I'm certain I'm not the first to think about it.

I strongly recomend you read this article "256bit keys for strong encryption" as well use the unit included to produce the 256bit keys.

Below is the entire unit. Credit is as always well appreciated!

//BRAVION (C)Copyright DrMungkee 2001

unit Bravion;
interface

type
  TBravionBlock8 = array[0..15] of byte;
  TBravionBlock32 = array[0..3] of longword;
  TBravionKey8 = array[0..31] of byte;
  TBravionKey32 = array[0..7] of longword;
  TBravionRoundKey32 = array[0..15] of TBravionBlock32;
  TBravionPathKey8 = array[0..23] of longword;

  TBravionContext = record
    RK: TBravionRoundKey32;
    PK: TBravionPathKey8;
  end;

procedure BravionInit(var Context: TBravionContext; var Key: TBravionKey32);
procedure BravionDecrypt(var Context: TBravionContext; var B: TBravionBlock32);
procedure BravionEncrypt(var Context: TBravionContext; var B: TBravionBlock32);

implementation
const
  //SUBSTITUTION BOXES FOR EACH ROUND
  S0: array[0..15, 0..255] of longword = ((
    $68, $9D, $A8, $7C, $0D, $E1, $C1, $21, $BC, $97, $84, $A2, $DE, $EE, $45, $BD,
    $17, $D8, $32, $D5, $A7, $1A, $64, $23, $1B, $B8, $07, $A1, $3B, $6E, $DF, $8D,
    $24, $50, $F4, $73, $C4, $59, $B7, $38, $D3, $47, $10, $E7, $93, $DD, $0A, $3C,
    $36, $AA, $9A, $B1, $75, $8E, $5B, $9B, $49, $33, $C8, $A4, $1C, $06, $20, $46,
    $88, $FA, $FC, $CC, $2E, $AD, $05, $1D, $86, $EF, $04, $3F, $6D, $0F, $D2, $5C,
    $DB, $5F, $0C, $71, $E3, $87, $A3, $8F, $AC, $9E, $0B, $AB, $EA, $5E, $AF, $16,
    $44, $E6, $39, $FB, $2A, $43, $3A, $F9, $48, $7E, $11, $08, $4C, $CB, $ED, $8B,
    $95, $C0, $01, $29, $4E, $B6, $63, $5D, $A9, $52, $56, $C5, $BB, $12, $81, $91,
    $F7, $7F, $4F, $3E, $2C, $F1, $EB, $54, $B5, $00, $6C, $8A, $26, $FF, $1E, $CA,
    $83, $9F, $D7, $EC, $77, $85, $B3, $F2, $CF, $28, $6B, $BF, $02, $96, $B0, $27,
    $F8, $F6, $DC, $D6, $7B, $65, $78, $60, $70, $82, $B9, $98, $BA, $62, $30, $61,
    $19, $B2, $09, $E9, $18, $79, $22, $14, $D9, $D1, $B4, $15, $E5, $F5, $92, $51,
    $80, $6A, $53, $89, $D4, $E0, $0E, $31, $76, $55, $4D, $9C, $94, $E4, $A0, $FE,
    $CD, $F3, $4A, $2F, $03, $1F, $69, $D0, $72, $F0, $AE, $8C, $E2, $41, $5A, $7D,
    $13, $74, $35, $42, $A6, $90, $25, $C7, $58, $2B, $6F, $C2, $66, $99, $E8, $3D,
    $C6, $C9, $57, $CE, $37, $67, $7A, $BE, $40, $2D, $34, $4B, $A5, $C3, $DA, $FD), (
    $78, $8D, $66, $CD, $1A, $9C, $0A, $FB, $D8, $3B, $9E, $6B, $73, $54, $45, $75,
    $15, $4C, $B5, $B1, $1B, $E0, $A3, $17, $2A, $57, $F0, $82, $07, $C5, $0C, $27,
    $88, $12, $A5, $1F, $8F, $D2, $18, $7B, $D3, $D9, $56, $F9, $05, $5C, $06, $68,
    $41, $6F, $94, $60, $C6, $C3, $6E, $E2, $D6, $11, $34, $19, $3D, $E5, $E1, $3E,
    $47, $B2, $DB, $F4, $B6, $CF, $F5, $10, $4B, $FA, $AB, $7F, $1C, $37, $46, $EE,
    $D7, $A6, $E9, $53, $FD, $CE, $EA, $8C, $84, $C7, $6C, $85, $9A, $D5, $28, $DC,
    $2B, $FF, $32, $EB, $77, $F2, $24, $4E, $9D, $03, $20, $81, $59, $DE, $C4, $6A,
    $A7, $89, $AE, $2E, $3A, $40, $86, $F8, $E4, $D1, $0B, $E8, $E7, $90, $D0, $08,
    $02, $B0, $4F, $B3, $C0, $92, $1D, $97, $7D, $E6, $99, $21, $9B, $83, $70, $AC,
    $C1, $80, $5E, $23, $5B, $4A, $65, $A8, $63, $61, $6D, $95, $16, $F1, $C2, $52,
    $96, $7C, $FE, $3F, $BD, $0D, $B4, $44, $ED, $42, $A0, $2C, $35, $22, $04, $0E,
    $D4, $51, $A2, $EC, $43, $AF, $B9, $EF, $39, $49, $2F, $69, $7E, $F3, $BF, $71,
    $67, $25, $8B, $8A, $01, $2D, $76, $79, $5F, $E3, $87, $3C, $31, $5A, $36, $1E,
    $9F, $98, $58, $CA, $A9, $BB, $DD, $AD, $A1, $50, $09, $33, $A4, $CB, $0F, $B8,
    $13, $14, $26, $29, $30, $38, $62, $FC, $72, $64, $DF, $00, $F7, $C8, $8E, $4D,
    $AA, $5D, $CC, $C9, $55, $74, $48, $DA, $91, $7A, $B7, $BC, $F6, $93, $BA, $BE), (
    $74, $8B, $4E, $20, $AC, $E8, $7A, $EF, $E2, $D6, $80, $BE, $A7, $05, $AA, $55,
    $C6, $DE, $1A, $5E, $1D, $30, $DA, $4B, $3D, $6D, $49, $4D, $5C, $9F, $77, $D1,
    $0E, $B3, $A5, $28, $0A, $F6, $E0, $83, $63, $7D, $3A, $E7, $E1, $C4, $7C, $27,
    $53, $54, $AD, $D3, $87, $F9, $FE, $A9, $1B, $F8, $99, $79, $43, $A1, $04, $46,
    $B2, $B4, $67, $CD, $F5, $14, $64, $BA, $16, $4F, $AE, $6A, $5B, $02, $DD, $32,
    $BF, $A4, $4C, $36, $2F, $10, $A6, $FA, $01, $8D, $ED, $FF, $7F, $93, $9A, $6F,
    $1C, $A3, $92, $B0, $97, $2B, $AF, $6B, $2D, $41, $FB, $EB, $78, $22, $C1, $91,
    $51, $15, $F1, $BC, $42, $6E, $70, $CB, $71, $C0, $25, $86, $8A, $18, $85, $98,
    $39, $F4, $E5, $00, $D5, $0F, $17, $45, $C3, $5F, $58, $2E, $C5, $7B, $B9, $40,
    $1F, $A0, $9C, $3E, $F2, $21, $31, $0B, $9B, $EA, $72, $5D, $76, $13, $3B, $52,
    $C8, $61, $09, $D2, $96, $75, $11, $94, $CF, $D0, $29, $06, $CC, $DF, $CE, $33,
    $62, $B5, $2C, $1E, $81, $88, $90, $A2, $26, $19, $84, $E3, $D8, $08, $3F, $F3,
    $8F, $AB, $B1, $BD, $50, $60, $23, $FC, $3C, $65, $EC, $07, $FD, $A8, $03, $E9,
    $DC, $95, $CA, $47, $35, $69, $0D, $38, $DB, $E4, $D4, $C9, $9D, $F0, $5A, $37,
    $B8, $6C, $C7, $4A, $68, $82, $66, $24, $7E, $89, $0C, $12, $2A, $34, $44, $48,
    $56, $57, $59, $73, $8C, $B6, $E6, $D7, $8E, $EE, $F7, $C2, $D9, $9E, $B7, $BB), (
    $DE, $9A, $C5, $FB, $93, $3E, $4E, $99, $68, $CC, $2E, $34, $07, $4F, $D1, $AB,
    $36, $50, $73, $19, $57, $F5, $16, $F8, $64, $D7, $37, $CA, $48, $62, $A9, $25,
    $3C, $3F, $0C, $C3, $A0, $DF, $D3, $C0, $3D, $66, $B2, $52, $94, $5E, $0E, $4D,
    $F0, $69, $8D, $AD, $EF, $4C, $29, $A1, $7C, $02, $23, $5D, $9E, $AC, $03, $97,
    $B5, $D6, $6B, $BA, $DC, $83, $C6, $AF, $F6, $9F, $F2, $09, $75, $76, $54, $15,
    $00, $DA, $8F, $71, $7B, $6F, $3A, $CE, $C1, $F1, $0F, $67, $B8, $C8, $ED, $45,
    $32, $1A, $2B, $6E, $B1, $BE, $85, $C7, $28, $BB, $C2, $82, $5F, $FD, $B0, $5B,
    $D5, $44, $61, $63, $7A, $0D, $1C, $E3, $F7, $A6, $8A, $98, $31, $7D, $11, $80,
    $A7, $EB, $A8, $22, $51, $E2, $F4, $47, $74, $A3, $14, $FF, $E6, $33, $42, $DD,
    $D8, $92, $01, $1D, $9C, $90, $EA, $BD, $8B, $B9, $E9, $24, $65, $7F, $D2, $6A,
    $81, $30, $9B, $B7, $E4, $60, $B3, $4A, $8C, $18, $B6, $53, $5A, $41, $B4, $3B,
    $D0, $F3, $2D, $87, $27, $26, $2A, $9D, $A4, $D4, $CF, $BC, $17, $72, $43, $46,
    $2F, $08, $91, $E0, $1F, $13, $88, $6C, $89, $8E, $38, $A2, $40, $C4, $AE, $FA,
    $FE, $E7, $EC, $78, $04, $84, $39, $E5, $77, $E8, $BF, $F9, $55, $59, $12, $21,
    $10, $86, $1B, $C9, $05, $A5, $FC, $49, $EE, $CB, $E1, $79, $DB, $96, $5C, $CD,
    $D9, $06, $0A, $0B, $1E, $20, $2C, $35, $4B, $56, $58, $6D, $70, $7E, $95, $AA), (
    $AE, $02, $85, $29, $A7, $FB, $64, $1C, $77, $78, $69, $F4, $D7, $27, $0F, $41,
    $54, $17, $A0, $03, $BB, $72, $E8, $3E, $C6, $3C, $65, $7D, $5E, $DD, $F7, $6B,
    $E1, $E9, $2A, $EC, $B0, $34, $35, $73, $BA, $6D, $32, $7A, $50, $2E, $8A, $3D,
    $12, $E6, $A6, $4A, $14, $8F, $31, $E2, $5D, $21, $CA, $8C, $48, $63, $8B, $92,
    $87, $BC, $16, $61, $E3, $5B, $08, $A5, $E7, $DA, $93, $3B, $94, $13, $0D, $9E,
    $07, $CE, $96, $38, $BE, $4F, $60, $66, $B3, $81, $F0, $B2, $36, $FE, $04, $FD,
    $C4, $0A, $75, $BF, $A4, $2C, $1D, $83, $42, $C1, $BD, $49, $C9, $B5, $9C, $79,
    $A1, $D8, $1B, $47, $D4, $74, $19, $24, $01, $51, $53, $EA, $ED, $1F, $67, $1E,
    $71, $D0, $6A, $2F, $62, $3A, $11, $AF, $B1, $57, $26, $43, $9A, $CB, $1A, $70,
    $C7, $7B, $39, $2B, $AB, $F2, $A9, $0B, $CC, $B9, $4B, $10, $DE, $E4, $FC, $D2,
    $AC, $CD, $EE, $00, $20, $AD, $68, $56, $D3, $AA, $6F, $15, $30, $7C, $28, $E5,
    $95, $25, $55, $5F, $0C, $D9, $C0, $A2, $59, $91, $C5, $82, $CF, $9B, $37, $A3,
    $F9, $F5, $C2, $22, $A8, $23, $4D, $B7, $FA, $40, $C3, $FF, $D5, $0E, $05, $97,
    $5C, $99, $18, $33, $D6, $F1, $B4, $DC, $B6, $D1, $09, $86, $8E, $F3, $52, $06,
    $2D, $7E, $EB, $C8, $7F, $3F, $44, $45, $46, $4C, $4E, $58, $88, $DF, $80, $84,
    $F8, $90, $9D, $9F, $F6, $8D, $B8, $89, $98, $EF, $5A, $DB, $E0, $6C, $6E, $76), (
    $5E, $63, $73, $A1, $FE, $6A, $8E, $C1, $5C, $D8, $1F, $D7, $B1, $97, $FB, $91,
    $78, $EB, $1C, $FA, $2C, $D5, $95, $B0, $40, $48, $89, $CE, $3C, $34, $43, $BF,
    $4A, $32, $9C, $5B, $71, $AF, $FD, $D2, $29, $18, $C0, $20, $72, $2B, $45, $0E,
    $C8, $55, $83, $15, $E5, $A7, $DB, $A5, $8D, $E7, $4F, $7D, $C3, $00, $D3, $85,
    $B5, $B4, $C2, $D9, $04, $88, $B8, $AE, $80, $C4, $99, $BB, $61, $13, $0C, $60,
    $6F, $9D, $AD, $56, $AA, $F1, $46, $8B, $F2, $8C, $F5, $F7, $51, $E4, $E6, $2F,
    $37, $12, $82, $67, $CA, $DF, $A6, $B3, $0F, $AB, $53, $44, $7F, $E9, $10, $1A,
    $7A, $9B, $92, $26, $81, $03, $DD, $C5, $11, $DA, $65, $BD, $4C, $42, $86, $E0,
    $31, $50, $84, $1D, $B2, $B6, $27, $14, $CF, $49, $D1, $30, $23, $52, $9E, $7C,
    $7E, $4B, $BA, $38, $BC, $3F, $EE, $6E, $02, $16, $74, $CB, $2A, $96, $E1, $E3,
    $35, $58, $06, $3D, $09, $3E, $E2, $93, $E8, $9A, $8F, $D4, $94, $F4, $47, $CD,
    $33, $3A, $A4, $05, $21, $66, $87, $22, $39, $70, $69, $1E, $F9, $75, $24, $79,
    $1B, $2E, $5A, $A2, $C6, $C7, $6B, $A8, $54, $D6, $5F, $F6, $EA, $08, $57, $FF,
    $28, $6D, $DC, $EF, $41, $BE, $0D, $FC, $7B, $DE, $76, $A9, $CC, $62, $01, $A3,
    $EC, $25, $59, $3B, $F8, $07, $0A, $0B, $17, $19, $2D, $36, $A0, $ED, $4E, $B7,
    $C9, $5D, $9F, $68, $AC, $64, $F3, $6C, $98, $4D, $D0, $8A, $77, $90, $F0, $B9), (
    $4D, $B2, $3C, $E6, $96, $B9, $9D, $C3, $A3, $9E, $FE, $1B, $76, $ED, $46, $31,
    $60, $C8, $3E, $98, $FF, $D0, $E2, $F8, $7D, $B8, $99, $FD, $64, $68, $BB, $40,
    $8B, $25, $2A, $DE, $4F, $E5, $88, $DB, $2B, $44, $32, $EB, $15, $C5, $5E, $F1,
    $3D, $01, $A4, $11, $BA, $5B, $8F, $0A, $37, $7F, $E0, $23, $7A, $2D, $EE, $1E,
    $A6, $29, $F7, $F0, $35, $4C, $63, $8A, $93, $92, $34, $B4, $4A, $89, $C4, $F6,
    $33, $9C, $FA, $0B, $38, $EA, $2F, $AD, $80, $E1, $1F, $BD, $91, $16, $5C, $9A,
    $12, $0D, $26, $82, $6C, $DF, $19, $1A, $54, $45, $F3, $D8, $A1, $3A, $65, $86,
    $77, $02, $B1, $74, $97, $BC, $6E, $CF, $F4, $7C, $B0, $8D, $50, $48, $FC, $41,
    $09, $81, $95, $6A, $D5, $59, $0E, $E3, $05, $C0, $78, $51, $A8, $87, $84, $D6,
    $C9, $E8, $C2, $14, $21, $49, $7E, $0C, $EC, $66, $13, $07, $C1, $10, $9B, $CD,
    $C7, $E9, $94, $5F, $B7, $B3, $AB, $3B, $FB, $06, $0F, $F9, $D1, $39, $53, $08,
    $6F, $CE, $D2, $61, $E7, $A0, $79, $55, $52, $30, $47, $B5, $04, $58, $75, $F5,
    $DD, $73, $71, $67, $BE, $43, $D4, $D9, $1D, $AC, $20, $DA, $A5, $70, $6B, $BF,
    $AF, $CC, $3F, $D3, $9F, $24, $DC, $28, $03, $17, $18, $1C, $22, $27, $85, $2E,
    $83, $56, $C6, $A9, $2C, $5A, $62, $72, $36, $00, $69, $8E, $CB, $42, $4E, $AE,
    $D7, $4B, $57, $A7, $A2, $EF, $E4, $CA, $5D, $6D, $F2, $7B, $8C, $90, $AA, $B6), (
    $0C, $56, $BF, $EE, $4F, $AB, $7D, $3E, $73, $98, $A8, $85, $05, $F4, $95, $3D,
    $C8, $D3, $67, $CA, $D2, $8C, $0D, $75, $47, $65, $CB, $63, $A2, $8F, $24, $C0,
    $18, $5A, $3B, $FA, $16, $77, $31, $A5, $71, $34, $E4, $66, $42, $FC, $EF, $E3,
    $DA, $D6, $92, $F1, $79, $EC, $C7, $4B, $99, $2D, $74, $12, $CD, $A9, $1B, $FF,
    $B2, $7F, $8A, $1F, $F3, $D0, $B1, $09, $8B, $59, $22, $DB, $D5, $84, $91, $57,
    $FE, $68, $C1, $C4, $6B, $87, $F0, $39, $17, $B7, $B0, $E8, $27, $1E, $9F, $2C,
    $BE, $1D, $E0, $7B, $E2, $94, $69, $20, $03, $64, $02, $4D, $ED, $7E, $AF, $19,
    $5D, $3C, $07, $6E, $36, $CC, $0E, $01, $51, $FD, $3F, $F5, $14, $DF, $0A, $93,
    $60, $40, $CF, $26, $53, $81, $2B, $B3, $43, $A6, $C6, $B4, $DD, $52, $A4, $61,
    $F6, $08, $28, $76, $7A, $46, $50, $7C, $C3, $A7, $9A, $13, $11, $4E, $04, $4A,
    $4C, $33, $6A, $A1, $2E, $83, $BA, $B8, $49, $44, $6F, $E1, $29, $C5, $88, $E9,
    $58, $90, $1A, $F7, $8D, $D8, $41, $15, $AC, $37, $F8, $E7, $89, $DC, $BC, $5B,
    $E6, $8E, $D7, $23, $1C, $9B, $48, $38, $97, $B6, $55, $2F, $E5, $5F, $B9, $80,
    $EA, $C9, $78, $6C, $30, $D1, $82, $AE, $D4, $9E, $00, $C2, $6D, $B5, $86, $DE,
    $9D, $45, $54, $AA, $D9, $BD, $5C, $96, $FB, $35, $0F, $CE, $9C, $10, $72, $0B,
    $70, $A3, $62, $A0, $25, $EB, $06, $21, $2A, $32, $3A, $5E, $AD, $BB, $F2, $F9), (
    $9F, $7E, $36, $84, $96, $8F, $B9, $F9, $32, $71, $93, $A7, $CB, $FA, $8E, $BA,
    $D3, $34, $7A, $6A, $E3, $B8, $90, $A5, $52, $A2, $48, $67, $CA, $02, $97, $E7,
    $F6, $40, $7C, $BF, $9A, $CD, $DB, $27, $5B, $1B, $63, $AC, $0A, $F3, $B6, $31,
    $C7, $80, $53, $4E, $ED, $C0, $CF, $19, $E1, $AA, $41, $E0, $07, $94, $57, $DD,
    $9E, $EF, $1E, $25, $74, $FF, $30, $33, $EB, $D5, $FD, $06, $99, $B4, $EE, $98,
    $1A, $47, $C1, $7D, $2C, $10, $51, $F0, $5D, $20, $38, $72, $EA, $43, $4D, $23,
    $FE, $87, $DA, $0E, $15, $14, $BB, $01, $6C, $8A, $85, $56, $82, $05, $BE, $16,
    $76, $2B, $EC, $D2, $44, $21, $61, $C8, $83, $49, $70, $F7, $F2, $AB, $37, $AF,
    $9C, $60, $E8, $E5, $7B, $4F, $AE, $39, $04, $CE, $3A, $03, $D1, $54, $7F, $50,
    $FB, $5E, $64, $24, $D7, $18, $86, $0D, $4B, $73, $A6, $3C, $69, $E6, $E4, $92,
    $E9, $AD, $F4, $28, $6F, $91, $0B, $D8, $2D, $9B, $62, $45, $2A, $6E, $6D, $8C,
    $59, $5C, $D9, $F8, $17, $66, $77, $A8, $8B, $DF, $78, $DE, $B3, $42, $79, $4C,
    $A3, $89, $D0, $55, $1F, $A4, $C6, $00, $75, $A9, $09, $0C, $81, $B5, $3D, $B7,
    $B2, $DC, $6B, $D6, $26, $9D, $3E, $95, $D4, $35, $3B, $E2, $65, $08, $4A, $13,
    $1C, $2E, $FC, $0F, $F5, $88, $C9, $BC, $12, $F1, $22, $3F, $B1, $68, $C5, $B0,
    $11, $1D, $29, $2F, $46, $58, $5A, $5F, $8D, $A0, $A1, $BD, $C3, $C4, $C2, $CC), (
    $EF, $8D, $10, $2A, $79, $42, $8C, $85, $D9, $83, $24, $12, $E9, $9F, $38, $67,
    $B2, $5C, $1A, $28, $36, $16, $B7, $11, $A5, $D2, $2E, $06, $1C, $FD, $E5, $41,
    $4F, $F4, $20, $AF, $3F, $3B, $05, $35, $9C, $A1, $DA, $3E, $7A, $CD, $F2, $B1,
    $FA, $7B, $E3, $F5, $5D, $FE, $ED, $1E, $26, $40, $F9, $BF, $46, $BE, $22, $4A,
    $EE, $5F, $6E, $77, $DE, $E8, $D0, $7D, $F6, $31, $2B, $B9, $99, $F3, $9D, $93,
    $A3, $A2, $7C, $68, $0A, $07, $6A, $C5, $03, $4C, $27, $C8, $3C, $0B, $4D, $56,
    $54, $CF, $73, $72, $49, $A8, $B5, $BC, $F1, $C4, $53, $69, $14, $9B, $47, $C0,
    $E0, $C2, $43, $13, $A6, $0C, $84, $E2, $29, $A7, $63, $D5, $2C, $74, $19, $0F,
    $CE, $1F, $0D, $DF, $C1, $97, $BB, $65, $C3, $61, $01, $7F, $6F, $3D, $5B, $FC,
    $87, $CA, $08, $B8, $09, $CC, $A9, $25, $86, $6D, $AE, $9A, $8A, $15, $66, $EA,
    $C7, $37, $58, $BD, $DD, $DC, $60, $91, $B3, $95, $B4, $33, $EC, $D7, $A0, $64,
    $2D, $98, $EB, $AD, $4B, $FB, $3A, $44, $71, $F8, $52, $A4, $9E, $E7, $89, $7E,
    $39, $B0, $D3, $94, $8F, $45, $E6, $B6, $CB, $0E, $92, $18, $5E, $30, $57, $AA,
    $02, $55, $D4, $48, $82, $6B, $E1, $D6, $8B, $21, $78, $75, $32, $90, $76, $70,
    $6C, $DB, $C6, $88, $04, $17, $1B, $1D, $23, $2F, $34, $4E, $50, $FF, $8E, $AB,
    $D8, $5A, $59, $AC, $00, $C9, $51, $BA, $F7, $D1, $62, $81, $80, $E4, $96, $F0), (
    $88, $DF, $B7, $A7, $8A, $CE, $44, $6C, $4F, $4D, $FD, $92, $4A, $56, $A4, $4B,
    $58, $D5, $FC, $E8, $F8, $F4, $3A, $43, $EF, $3E, $01, $AC, $36, $2E, $F2, $28,
    $09, $C3, $67, $D3, $A1, $29, $DE, $50, $79, $14, $78, $97, $26, $9C, $24, $AD,
    $15, $E9, $6B, $7B, $96, $87, $2D, $30, $9B, $8D, $89, $21, $4E, $20, $C8, $5A,
    $6E, $71, $06, $33, $74, $E2, $9F, $85, $BD, $EB, $34, $DB, $BE, $B1, $A0, $1B,
    $93, $CF, $1A, $E0, $5D, $59, $52, $46, $2C, $2B, $37, $CB, $FB, $38, $95, $9A,
    $BC, $32, $AF, $8B, $DA, $11, $68, $B2, $5E, $23, $D8, $22, $7C, $91, $E4, $C2,
    $41, $EE, $ED, $17, $05, $3D, $1C, $08, $83, $80, $4C, $D2, $5B, $9D, $3B, $02,
    $C4, $C1, $7E, $F3, $BA, $12, $51, $72, $FE, $E5, $62, $70, $60, $EA, $35, $99,
    $8C, $65, $BF, $45, $6D, $8E, $DD, $A9, $CA, $F0, $98, $53, $66, $D4, $AE, $B3,
    $10, $5C, $F7, $0E, $18, $A8, $0F, $B0, $EC, $76, $AA, $A6, $F5, $3F, $D6, $F6,
    $E7, $55, $82, $C9, $AB, $B6, $D0, $04, $C5, $7F, $86, $77, $07, $0C, $5F, $16,
    $81, $63, $C7, $40, $31, $54, $B5, $49, $90, $FF, $27, $75, $7A, $CD, $48, $13,
    $1D, $03, $D9, $D1, $E6, $0A, $84, $69, $C6, $B9, $B8, $C0, $A3, $B4, $94, $A2,
    $D7, $F9, $9E, $6A, $1F, $1E, $0D, $DC, $E3, $CC, $3C, $0B, $6F, $2A, $00, $7D,
    $39, $42, $BB, $19, $73, $61, $25, $2F, $47, $57, $64, $8F, $A5, $E1, $F1, $FA), (
    $61, $C1, $70, $D5, $26, $07, $09, $EB, $8B, $5F, $28, $E5, $64, $91, $46, $32,
    $E0, $72, $9A, $11, $C0, $45, $66, $99, $1D, $8D, $40, $62, $55, $EE, $BB, $5C,
    $94, $E6, $1F, $00, $A2, $76, $1B, $34, $78, $0F, $2C, $F6, $97, $4D, $3F, $21,
    $6E, $BA, $83, $8F, $B0, $9B, $9E, $2E, $F0, $C4, $FF, $71, $A4, $35, $D8, $69,
    $88, $4C, $DB, $1A, $BD, $30, $C7, $47, $80, $90, $17, $A5, $50, $0A, $C3, $57,
    $18, $03, $49, $37, $D4, $F8, $CE, $20, $CB, $65, $85, $02, $4A, $DA, $14, $24,
    $75, $7A, $48, $A1, $CC, $98, $73, $FD, $C2, $FA, $E7, $68, $AB, $B3, $0C, $D2,
    $FC, $53, $5A, $81, $2D, $63, $D3, $33, $DE, $95, $BC, $F2, $44, $4B, $B7, $5D,
    $AE, $EC, $B4, $1E, $9C, $DC, $7E, $9D, $8A, $25, $B1, $A8, $22, $D9, $B8, $D0,
    $82, $BF, $67, $6A, $01, $0D, $C9, $6B, $AA, $CA, $AC, $A9, $DD, $3C, $8E, $3B,
    $F5, $F9, $C8, $23, $C5, $6F, $3A, $08, $51, $E4, $C6, $D6, $84, $87, $A6, $0E,
    $FB, $A0, $0B, $E2, $8C, $1C, $15, $E1, $60, $B9, $10, $E8, $74, $5B, $9F, $ED,
    $2B, $B2, $29, $7F, $E9, $F7, $36, $F4, $3D, $A3, $D1, $58, $38, $93, $04, $6D,
    $B5, $AF, $05, $27, $31, $CF, $E3, $7B, $4F, $5E, $2F, $B6, $52, $7D, $42, $39,
    $06, $12, $13, $59, $D7, $16, $CD, $3E, $4E, $BE, $92, $A7, $F3, $77, $EA, $79,
    $89, $43, $AD, $86, $DF, $19, $41, $FE, $6C, $7C, $2A, $96, $54, $56, $EF, $F1), (
    $99, $09, $EE, $E3, $4B, $6E, $04, $D0, $F6, $76, $8F, $EA, $A7, $2F, $EB, $D8,
    $A9, $83, $96, $C8, $F7, $64, $B3, $54, $28, $9B, $B2, $9E, $41, $DF, $CD, $06,
    $33, $65, $1F, $80, $4C, $E0, $0C, $B6, $39, $90, $7C, $50, $3C, $B8, $73, $91,
    $92, $A2, $C5, $51, $C7, $1A, $4F, $21, $08, $A8, $36, $8B, $6A, $82, $86, $7E,
    $59, $95, $D6, $B5, $FC, $37, $02, $B1, $16, $6C, $B0, $C9, $55, $B9, $DE, $F5,
    $61, $98, $D4, $63, $C6, $FE, $BA, $C2, $24, $4A, $97, $5F, $67, $ED, $01, $2C,
    $46, $9F, $3D, $A0, $23, $58, $62, $13, $2B, $34, $D2, $8E, $D1, $00, $70, $68,
    $15, $2E, $31, $45, $A4, $EC, $81, $F4, $F3, $A3, $1C, $75, $07, $F0, $DA, $27,
    $CB, $CE, $0F, $1B, $BB, $5B, $F2, $CF, $77, $D9, $18, $7B, $29, $EF, $FB, $D5,
    $BE, $3F, $5E, $52, $8D, $26, $A1, $0E, $A5, $1D, $93, $43, $B7, $20, $F1, $38,
    $57, $5C, $94, $A6, $79, $E9, $7D, $40, $F9, $0B, $DC, $25, $FD, $BC, $49, $BD,
    $44, $AA, $6B, $12, $22, $4D, $0A, $53, $6D, $2D, $7A, $F8, $42, $C3, $4E, $7F,
    $60, $E8, $19, $AF, $D7, $71, $78, $1E, $AD, $CA, $6F, $AC, $11, $0D, $8C, $C1,
    $5A, $E7, $E2, $CC, $17, $30, $74, $3A, $BF, $3E, $88, $D3, $84, $66, $B4, $9A,
    $87, $03, $05, $10, $14, $2A, $32, $69, $9C, $5D, $9D, $85, $E6, $AB, $48, $E1,
    $FA, $3B, $72, $AE, $DD, $35, $89, $E5, $8A, $47, $C0, $56, $FF, $C4, $DB, $E4), (
    $81, $13, $59, $92, $52, $E4, $BF, $02, $B7, $19, $FD, $87, $53, $2E, $F2, $80,
    $CF, $12, $4F, $0A, $9B, $63, $9A, $E3, $68, $CB, $36, $EC, $C8, $2D, $34, $D3,
    $31, $56, $F4, $62, $A4, $D4, $71, $ED, $DB, $B0, $B3, $8C, $5A, $D8, $2C, $8D,
    $90, $B6, $91, $1C, $7D, $E7, $C5, $65, $F0, $21, $FA, $17, $57, $64, $B2, $75,
    $38, $6D, $10, $16, $C9, $E5, $A2, $6A, $0B, $09, $94, $54, $C0, $BE, $42, $95,
    $1A, $44, $66, $6B, $30, $73, $7C, $50, $99, $9D, $9E, $A9, $FB, $C4, $E2, $AD,
    $6E, $A3, $9C, $55, $EE, $72, $84, $8A, $46, $D2, $28, $A6, $6F, $AE, $74, $F3,
    $48, $BB, $35, $1F, $D7, $CC, $AC, $D1, $DD, $5D, $A7, $AA, $76, $3D, $8E, $D0,
    $24, $2F, $EB, $DC, $41, $8F, $97, $0F, $3A, $DF, $B9, $DE, $D9, $BD, $7E, $47,
    $5B, $14, $40, $FC, $4D, $58, $26, $C3, $29, $11, $4A, $43, $77, $EF, $33, $3B,
    $A5, $3E, $88, $1E, $B5, $7F, $4E, $E0, $61, $F8, $DA, $E6, $7A, $03, $A0, $C1,
    $BA, $78, $9F, $EA, $E8, $AB, $69, $07, $F9, $E9, $82, $93, $51, $D6, $F1, $FF,
    $39, $89, $E1, $1D, $A1, $C7, $F7, $37, $CD, $96, $6C, $67, $D5, $B4, $BC, $60,
    $B1, $70, $3F, $27, $85, $83, $7B, $C6, $20, $0C, $B8, $CE, $86, $F6, $0E, $AF,
    $5F, $01, $04, $15, $23, $0D, $32, $F5, $22, $00, $18, $4B, $A8, $98, $FE, $2B,
    $45, $8B, $5C, $5E, $79, $06, $25, $1B, $05, $CA, $49, $2A, $08, $3C, $C2, $4C), (
    $41, $EB, $7F, $0F, $02, $6F, $C4, $47, $D9, $04, $37, $4C, $EF, $A3, $BC, $B6,
    $17, $5B, $E4, $11, $1C, $18, $96, $6C, $AF, $58, $87, $50, $0A, $59, $E9, $3E,
    $49, $90, $DF, $07, $F1, $D7, $CD, $AE, $82, $2A, $34, $C8, $E0, $7C, $19, $C0,
    $9C, $D1, $BE, $31, $E7, $D6, $51, $AA, $EE, $F3, $28, $27, $8F, $A8, $05, $21,
    $B7, $78, $E8, $33, $A6, $4D, $DE, $7D, $16, $2B, $9F, $67, $CF, $65, $3B, $BB,
    $25, $C3, $6E, $72, $6A, $DD, $C2, $06, $C1, $10, $AD, $EC, $CE, $5F, $F6, $00,
    $03, $EA, $29, $FF, $83, $A9, $92, $A7, $53, $71, $7E, $61, $35, $43, $5D, $B8,
    $D4, $A4, $A2, $F2, $2D, $30, $DC, $1E, $5C, $88, $57, $24, $E2, $7A, $E1, $48,
    $4A, $98, $38, $CA, $5E, $13, $62, $A0, $D5, $F9, $C7, $8B, $54, $80, $BA, $81,
    $66, $A5, $F5, $1A, $CB, $6D, $D0, $E3, $F7, $C5, $09, $C6, $23, $20, $55, $94,
    $B5, $74, $2C, $26, $1B, $01, $BF, $14, $93, $56, $42, $40, $D3, $B9, $39, $FE,
    $8D, $E5, $12, $3A, $3F, $AB, $0B, $ED, $FC, $44, $85, $5A, $DB, $DA, $FB, $7B,
    $B1, $63, $9D, $0C, $B3, $8E, $46, $45, $F8, $68, $BD, $77, $FA, $9B, $69, $75,
    $76, $36, $99, $79, $FD, $91, $70, $3D, $08, $22, $95, $B0, $F4, $B4, $0E, $64,
    $89, $F0, $C9, $2F, $97, $52, $86, $D8, $CC, $4E, $60, $8A, $8C, $4F, $B2, $4B,
    $84, $2E, $AC, $A1, $32, $E6, $0D, $9A, $3C, $1D, $15, $1F, $6B, $73, $9E, $D2), (
    $BE, $B5, $90, $5C, $C9, $3A, $23, $DF, $78, $00, $F1, $E7, $B8, $ED, $FB, $B3,
    $1F, $F6, $6C, $12, $88, $32, $E8, $1C, $C8, $07, $5A, $C2, $25, $65, $B7, $CE,
    $47, $CD, $70, $4B, $FC, $53, $DB, $93, $EF, $AB, $6A, $92, $39, $02, $56, $81,
    $5E, $51, $1D, $30, $35, $7C, $5F, $A9, $BF, $29, $0A, $76, $DA, $DC, $67, $46,
    $96, $19, $10, $0C, $9F, $C1, $43, $3F, $57, $74, $F3, $44, $79, $F7, $BA, $E4,
    $6D, $F9, $4A, $34, $8D, $D5, $D8, $2A, $63, $05, $0B, $0E, $2D, $CC, $01, $18,
    $D4, $EA, $E9, $31, $94, $15, $AA, $F8, $E1, $C3, $E6, $59, $91, $69, $48, $6E,
    $20, $4D, $55, $45, $8A, $11, $66, $16, $F5, $1E, $03, $B1, $21, $9A, $38, $8B,
    $D6, $CB, $F2, $D2, $B4, $4E, $3E, $D3, $2E, $EE, $24, $FE, $C5, $77, $33, $E2,
    $54, $2C, $C6, $41, $BD, $17, $A0, $13, $D0, $40, $F0, $50, $A3, $EC, $CF, $FF,
    $99, $DD, $D1, $09, $61, $AD, $1A, $AF, $89, $CA, $EB, $A5, $84, $8E, $3C, $3B,
    $A4, $B0, $82, $8F, $83, $A1, $1B, $E5, $9C, $C0, $7A, $95, $3D, $52, $26, $9B,
    $C4, $42, $7F, $F4, $9E, $08, $AC, $72, $D9, $0D, $AE, $FD, $FA, $49, $A7, $D7,
    $B6, $62, $36, $68, $4F, $0F, $C7, $2F, $22, $BB, $9D, $04, $BC, $B2, $A8, $27,
    $E3, $14, $A6, $7B, $06, $64, $28, $6B, $80, $A2, $97, $87, $73, $7D, $75, $8C,
    $60, $85, $7E, $5D, $5B, $58, $37, $2B, $E0, $6F, $4C, $71, $86, $98, $B9, $DE));

  //SUBSTITUTION BOXES' INVERSE FOR EACH ROUND
  S1: array[0..15, 0..255] of longword = ((
    $89, $72, $9C, $D4, $4A, $46, $3D, $1A, $6B, $B2, $2E, $5A, $52, $04, $C6, $4D,
    $2A, $6A, $7D, $E0, $B7, $BB, $5F, $10, $B4, $B0, $15, $18, $3C, $47, $8E, $D5,
    $3E, $07, $B6, $17, $20, $E6, $8C, $9F, $99, $73, $64, $E9, $84, $F9, $44, $D3,
    $AE, $C7, $12, $39, $FA, $E2, $30, $F4, $27, $62, $66, $1C, $2F, $EF, $83, $4B,
    $F8, $DD, $E3, $65, $60, $0E, $3F, $29, $68, $38, $D2, $FB, $6C, $CA, $74, $82,
    $21, $BF, $79, $C2, $87, $C9, $7A, $F2, $E8, $25, $DE, $36, $4F, $77, $5D, $51,
    $A7, $AF, $AD, $76, $16, $A5, $EC, $F5, $00, $D6, $C1, $9A, $8A, $4C, $1D, $EA,
    $A8, $53, $D8, $23, $E1, $34, $C8, $94, $A6, $B5, $F6, $A4, $03, $DF, $69, $81,
    $C0, $7E, $A9, $90, $0A, $95, $48, $55, $40, $C3, $8B, $6F, $DB, $1F, $35, $57,
    $E5, $7F, $BE, $2C, $CC, $70, $9D, $09, $AB, $ED, $32, $37, $CB, $01, $59, $91,
    $CE, $1B, $0B, $56, $3B, $FC, $E4, $14, $02, $78, $31, $5B, $58, $45, $DA, $5E,
    $9E, $33, $B1, $96, $BA, $88, $75, $26, $19, $AA, $AC, $7C, $08, $0F, $F7, $9B,
    $71, $06, $EB, $FD, $24, $7B, $F0, $E7, $3A, $F1, $8F, $6D, $43, $D0, $F3, $98,
    $D7, $B9, $4E, $28, $C4, $13, $A3, $92, $11, $B8, $FE, $50, $A2, $2D, $0C, $1E,
    $C5, $05, $DC, $54, $CD, $BC, $61, $2B, $EE, $B3, $5C, $86, $93, $6E, $0D, $49,
    $D9, $85, $97, $D1, $22, $BD, $A1, $80, $A0, $67, $41, $63, $42, $FF, $CF, $8D), (
    $EB, $C4, $80, $69, $AE, $2C, $2E, $1C, $7F, $DA, $06, $7A, $1E, $A5, $AF, $DE,
    $47, $39, $21, $E0, $E1, $10, $9C, $17, $26, $3B, $04, $14, $4C, $86, $CF, $23,
    $6A, $8B, $AD, $93, $66, $C1, $E2, $1F, $5E, $E3, $18, $60, $AB, $C5, $73, $BA,
    $E4, $CC, $62, $DB, $3A, $AC, $CE, $4D, $E5, $B8, $74, $09, $CB, $3C, $3F, $A3,
    $75, $30, $A9, $B4, $A7, $0E, $4E, $40, $F6, $B9, $95, $48, $11, $EF, $67, $82,
    $D9, $B1, $9F, $53, $0D, $F4, $2A, $19, $D2, $6C, $CD, $94, $2D, $F1, $92, $C8,
    $33, $99, $E6, $98, $E9, $96, $02, $C0, $2F, $BB, $6F, $0B, $5A, $9A, $36, $31,
    $8E, $BF, $E8, $0C, $F5, $0F, $C6, $64, $00, $C7, $F9, $27, $A1, $88, $BC, $4B,
    $91, $6B, $1B, $8D, $58, $5B, $76, $CA, $20, $71, $C3, $C2, $57, $01, $EE, $24,
    $7D, $F8, $85, $FD, $32, $9B, $A0, $87, $D1, $8A, $5C, $8C, $05, $68, $0A, $D0,
    $AA, $D8, $B2, $16, $DC, $22, $51, $70, $97, $D4, $F0, $4A, $8F, $D7, $72, $B5,
    $81, $13, $41, $83, $A6, $12, $44, $FA, $DF, $B6, $FE, $D5, $FB, $A4, $FF, $BE,
    $84, $90, $9E, $35, $6E, $1D, $34, $59, $ED, $F3, $D3, $DD, $F2, $03, $55, $45,
    $7E, $79, $25, $28, $B0, $5D, $38, $50, $08, $29, $F7, $42, $5F, $D6, $6D, $EA,
    $15, $3E, $37, $C9, $78, $3D, $89, $7C, $7B, $52, $56, $63, $B3, $A8, $4F, $B7,
    $1A, $9D, $65, $BD, $43, $46, $FC, $EC, $77, $2B, $49, $07, $E7, $54, $A2, $61), (
    $83, $58, $4D, $CE, $3E, $0D, $AB, $CB, $BD, $A2, $24, $97, $EA, $D6, $20, $85,
    $55, $A6, $EB, $9D, $45, $71, $48, $86, $7D, $B9, $12, $38, $60, $14, $B3, $90,
    $03, $95, $6D, $C6, $E7, $7A, $B8, $2F, $23, $AA, $EC, $65, $B2, $68, $8B, $54,
    $15, $96, $4F, $AF, $ED, $D4, $53, $DF, $D7, $80, $2A, $9E, $C8, $18, $93, $BE,
    $8F, $69, $74, $3C, $EE, $87, $3F, $D3, $EF, $1A, $E3, $17, $52, $1B, $02, $49,
    $C4, $70, $9F, $30, $31, $0F, $F0, $F1, $8A, $F2, $DE, $4C, $1C, $9B, $13, $89,
    $C5, $A1, $B0, $28, $46, $C9, $E6, $42, $E4, $D5, $4B, $67, $E1, $19, $75, $5F,
    $76, $78, $9A, $F3, $00, $A5, $9C, $1E, $6C, $3B, $06, $8D, $2E, $29, $E8, $5C,
    $0A, $B4, $E5, $27, $BA, $7E, $7B, $34, $B5, $E9, $7C, $01, $F4, $59, $F8, $C0,
    $B6, $6F, $62, $5D, $A7, $D1, $A4, $64, $7F, $3A, $5E, $98, $92, $DC, $FD, $1D,
    $91, $3D, $B7, $61, $51, $22, $56, $0C, $CD, $37, $0E, $C1, $04, $32, $4A, $66,
    $63, $C2, $40, $21, $41, $B1, $F5, $FE, $E0, $8E, $47, $FF, $73, $C3, $0B, $50,
    $79, $6E, $FB, $88, $2D, $8C, $10, $E2, $A0, $DB, $D2, $77, $AC, $43, $AE, $A8,
    $A9, $1F, $A3, $33, $DA, $84, $09, $F7, $BC, $FC, $16, $D8, $D0, $4E, $11, $AD,
    $26, $2C, $08, $BB, $D9, $82, $F6, $2B, $05, $CF, $99, $6B, $CA, $5A, $F9, $07,
    $DD, $72, $94, $BF, $81, $44, $25, $FA, $39, $35, $57, $6A, $C7, $CC, $36, $5B), (
    $50, $92, $39, $3E, $D4, $E4, $F1, $0C, $C1, $4B, $F2, $F3, $22, $75, $2E, $5A,
    $E0, $7E, $DE, $C5, $8A, $4F, $16, $BC, $A9, $13, $61, $E2, $76, $93, $F4, $C4,
    $F5, $DF, $83, $3A, $9B, $1F, $B5, $B4, $68, $36, $B6, $62, $F6, $B2, $0A, $C0,
    $A1, $7C, $60, $8D, $0B, $F7, $10, $1A, $CA, $D6, $56, $AF, $20, $28, $05, $21,
    $CC, $AD, $8E, $BE, $71, $5F, $BF, $87, $1C, $E7, $A7, $F8, $35, $2F, $06, $0D,
    $11, $84, $2B, $AB, $4E, $DC, $F9, $14, $FA, $DD, $AC, $6F, $EE, $3B, $2D, $6C,
    $A5, $72, $1D, $73, $18, $9C, $29, $5B, $08, $31, $9F, $42, $C7, $FB, $63, $55,
    $FC, $53, $BD, $12, $88, $4C, $4D, $D8, $D3, $EB, $74, $54, $38, $7D, $FD, $9D,
    $7F, $A0, $6B, $45, $D5, $66, $E1, $B3, $C6, $C8, $7A, $98, $A8, $32, $C9, $52,
    $95, $C2, $91, $04, $2C, $FE, $ED, $3F, $7B, $07, $01, $A2, $94, $B7, $3C, $49,
    $24, $37, $CB, $89, $B8, $E5, $79, $80, $82, $1E, $FF, $0F, $3D, $33, $CE, $47,
    $6E, $64, $2A, $A6, $AE, $40, $AA, $A3, $5C, $99, $43, $69, $BB, $97, $65, $DA,
    $27, $58, $6A, $23, $CD, $02, $46, $67, $5D, $E3, $1B, $E9, $09, $EF, $57, $BA,
    $B0, $0E, $9E, $26, $B9, $70, $41, $19, $90, $F0, $51, $EC, $44, $8F, $00, $25,
    $C3, $EA, $85, $77, $A4, $D7, $8C, $D1, $D9, $9A, $96, $81, $D2, $5E, $E8, $34,
    $30, $59, $4A, $B1, $86, $15, $48, $78, $17, $DB, $CF, $03, $E6, $6D, $D0, $8B), (
    $A3, $78, $01, $13, $5E, $CE, $DF, $50, $46, $DA, $61, $97, $B4, $4E, $CD, $0E,
    $9B, $86, $30, $4D, $34, $AB, $42, $11, $D2, $76, $8E, $72, $07, $66, $7F, $7D,
    $A4, $39, $C3, $C5, $77, $B1, $8A, $0D, $AE, $03, $22, $93, $65, $E0, $2D, $83,
    $AC, $36, $2A, $D3, $25, $26, $5C, $BE, $53, $92, $85, $4B, $19, $2F, $17, $E5,
    $C9, $0F, $68, $8B, $E6, $E7, $E8, $73, $3C, $6B, $33, $9A, $E9, $C6, $EA, $55,
    $2C, $79, $DE, $7A, $10, $B2, $A7, $89, $EB, $B8, $FA, $45, $D0, $38, $1C, $B3,
    $56, $43, $84, $3D, $06, $1A, $57, $7E, $A6, $0A, $82, $1F, $FD, $29, $FE, $AA,
    $8F, $80, $15, $27, $75, $62, $FF, $08, $09, $6F, $2B, $91, $AD, $1B, $E1, $E4,
    $EE, $59, $BB, $67, $EF, $02, $DB, $40, $EC, $F7, $2E, $3E, $3B, $F5, $DC, $35,
    $F1, $B9, $3F, $4A, $4C, $B0, $52, $CF, $F8, $D1, $8C, $BD, $6E, $F2, $4F, $F3,
    $12, $70, $B7, $BF, $64, $47, $32, $04, $C4, $96, $A9, $94, $A0, $A5, $00, $87,
    $24, $88, $5B, $58, $D6, $6D, $D8, $C7, $F6, $99, $28, $14, $41, $6A, $54, $63,
    $B6, $69, $C2, $CA, $60, $BA, $18, $90, $E3, $6C, $3A, $8D, $98, $A1, $51, $BC,
    $81, $D9, $9F, $A8, $74, $CC, $D4, $0C, $71, $B5, $49, $FB, $D7, $1D, $9C, $ED,
    $FC, $20, $37, $44, $9D, $AF, $31, $48, $16, $21, $7B, $E2, $23, $7C, $A2, $F9,
    $5A, $D5, $95, $DD, $0B, $C1, $F4, $1E, $F0, $C0, $C8, $05, $9E, $5F, $5D, $CB), (
    $3D, $DE, $98, $75, $44, $B3, $A2, $E5, $CD, $A4, $E6, $E7, $4E, $D6, $2F, $68,
    $6E, $78, $61, $4D, $87, $33, $99, $E8, $29, $E9, $6F, $C0, $12, $83, $BB, $0A,
    $2B, $B4, $B7, $8C, $BE, $E1, $73, $86, $D0, $28, $9C, $2D, $14, $EA, $C1, $5F,
    $8B, $80, $21, $B0, $1D, $A0, $EB, $60, $93, $B8, $B1, $E3, $1C, $A3, $A5, $95,
    $18, $D4, $7D, $1E, $6B, $2E, $56, $AE, $19, $89, $20, $91, $7C, $F9, $EE, $3A,
    $81, $5C, $8D, $6A, $C8, $31, $53, $CE, $A1, $E2, $C2, $23, $08, $F1, $00, $CA,
    $4F, $4C, $DD, $01, $F5, $7A, $B5, $63, $F3, $BA, $05, $C6, $F7, $D1, $97, $50,
    $B9, $24, $2C, $02, $9A, $BD, $DA, $FC, $10, $BF, $70, $D8, $8F, $3B, $90, $6C,
    $48, $74, $62, $32, $82, $3F, $7E, $B6, $45, $1A, $FB, $57, $59, $38, $06, $AA,
    $FD, $0F, $72, $A7, $AC, $16, $9D, $0D, $F8, $4A, $A9, $71, $22, $51, $8E, $F2,
    $EC, $03, $C3, $DF, $B2, $37, $66, $35, $C7, $DB, $54, $69, $F4, $52, $47, $25,
    $17, $0C, $84, $67, $41, $40, $85, $EF, $46, $FF, $92, $4B, $94, $7B, $D5, $1F,
    $2A, $07, $42, $3C, $49, $77, $C4, $C5, $30, $F0, $64, $9B, $DC, $AF, $1B, $88,
    $FA, $8A, $27, $3E, $AB, $15, $C9, $0B, $09, $43, $79, $36, $D2, $76, $D9, $65,
    $7F, $9E, $A6, $9F, $5D, $34, $5E, $39, $A8, $6D, $CC, $11, $E0, $ED, $96, $D3,
    $FE, $55, $58, $F6, $AD, $5A, $CB, $5B, $E4, $BC, $13, $0E, $D7, $26, $04, $CF), (
    $E9, $31, $71, $D8, $BC, $88, $A9, $9B, $AF, $80, $37, $53, $97, $61, $86, $AA,
    $9D, $33, $60, $9A, $93, $2C, $5D, $D9, $DA, $66, $67, $0B, $DB, $C8, $3F, $5A,
    $CA, $94, $DC, $3B, $D5, $21, $62, $DD, $D7, $41, $22, $28, $E4, $3D, $DF, $56,
    $B9, $0F, $2A, $50, $4A, $44, $E8, $38, $54, $AD, $6D, $A7, $02, $30, $12, $D2,
    $1F, $7F, $ED, $C5, $29, $69, $0E, $BA, $7D, $95, $4C, $F1, $45, $00, $EE, $24,
    $7C, $8B, $B8, $AE, $68, $B7, $E1, $F2, $BD, $85, $E5, $35, $5E, $F8, $2E, $A3,
    $10, $B3, $E6, $46, $1C, $6E, $99, $C3, $1D, $EA, $83, $CE, $64, $F9, $76, $B0,
    $CD, $C2, $E7, $C1, $73, $BE, $0C, $70, $8A, $B6, $3C, $FB, $79, $18, $96, $39,
    $58, $81, $63, $E0, $8E, $DE, $6F, $8D, $26, $4D, $47, $20, $FC, $7B, $EB, $36,
    $FD, $5C, $49, $48, $A2, $82, $04, $74, $13, $1A, $5F, $9E, $51, $06, $09, $D4,
    $B5, $6C, $F4, $08, $32, $CC, $40, $F3, $8C, $E3, $FE, $A6, $C9, $57, $EF, $D0,
    $7A, $72, $01, $A5, $4B, $BB, $FF, $A4, $19, $05, $34, $1E, $75, $5B, $C4, $CF,
    $89, $9C, $92, $07, $4E, $2D, $E2, $A0, $11, $90, $F7, $EC, $D1, $9F, $B1, $77,
    $15, $AC, $B2, $D3, $C6, $84, $8F, $F0, $6B, $C7, $CB, $27, $D6, $C0, $23, $65,
    $3A, $59, $16, $87, $F6, $25, $03, $B4, $91, $A1, $55, $2B, $98, $0D, $3E, $F5,
    $43, $2F, $FA, $6A, $78, $BF, $4F, $42, $17, $AB, $52, $A8, $7E, $1B, $0A, $14), (
    $DA, $77, $6A, $68, $9E, $0C, $F6, $72, $91, $47, $7E, $EF, $00, $16, $76, $EA,
    $ED, $9C, $3B, $9B, $7C, $B7, $24, $58, $20, $6F, $B2, $3E, $C4, $61, $5D, $43,
    $67, $F7, $4A, $C3, $1E, $F4, $83, $5C, $92, $AC, $F8, $86, $5F, $39, $A4, $CB,
    $D4, $26, $F9, $A1, $29, $E9, $74, $B9, $C7, $57, $FA, $22, $71, $0F, $07, $7A,
    $81, $B6, $2C, $88, $A9, $E1, $95, $18, $C6, $A8, $9F, $37, $A0, $6B, $9D, $04,
    $96, $78, $8D, $84, $E2, $CA, $01, $4F, $B0, $49, $21, $BF, $E6, $70, $FB, $CD,
    $80, $8F, $F2, $1B, $69, $19, $2B, $12, $51, $66, $A2, $54, $D3, $DC, $73, $AA,
    $F0, $28, $EE, $08, $3A, $17, $93, $25, $D2, $34, $94, $63, $97, $06, $6D, $41,
    $CF, $85, $D6, $A5, $4D, $0B, $DE, $55, $AE, $BC, $42, $48, $15, $B4, $C1, $1D,
    $B1, $4E, $32, $7F, $65, $0E, $E7, $C8, $09, $38, $9A, $C5, $EC, $E0, $D9, $5E,
    $F3, $A3, $1C, $F1, $8E, $27, $89, $99, $0A, $3D, $E3, $05, $B8, $FC, $D7, $6E,
    $5A, $46, $40, $87, $8B, $DD, $C9, $59, $A7, $CE, $A6, $FD, $BE, $E5, $60, $02,
    $1F, $52, $DB, $98, $53, $AD, $8A, $36, $10, $D1, $13, $1A, $75, $3C, $EB, $82,
    $45, $D5, $14, $11, $D8, $4C, $31, $C2, $B5, $E4, $30, $4B, $BD, $8C, $DF, $7D,
    $62, $AB, $64, $2F, $2A, $CC, $C0, $BB, $5B, $AF, $D0, $F5, $35, $6C, $03, $2E,
    $56, $33, $FE, $44, $0D, $7B, $90, $B3, $BA, $FF, $23, $E8, $2D, $79, $50, $3F), (
    $C7, $67, $1D, $8B, $88, $6D, $4B, $3C, $DD, $CA, $2C, $A6, $CB, $97, $63, $E3,
    $55, $F0, $E8, $DF, $65, $64, $6F, $B4, $95, $37, $50, $29, $E0, $F1, $42, $C4,
    $59, $75, $EA, $5F, $93, $43, $D4, $27, $A3, $F2, $AC, $71, $54, $A8, $E1, $F3,
    $46, $2F, $08, $47, $11, $D9, $02, $7E, $5A, $87, $8A, $DA, $9B, $CE, $D6, $EB,
    $21, $3A, $BD, $5D, $74, $AB, $F4, $51, $1A, $79, $DE, $98, $BF, $5E, $33, $85,
    $8F, $56, $18, $32, $8D, $C3, $6B, $3E, $F5, $B0, $F6, $28, $B1, $58, $91, $F7,
    $81, $76, $AA, $2A, $92, $DC, $B5, $1B, $ED, $9C, $13, $D2, $68, $AE, $AD, $A4,
    $7A, $09, $5B, $99, $44, $C8, $70, $B6, $BA, $BE, $12, $84, $22, $53, $01, $8E,
    $31, $CC, $6C, $78, $03, $6A, $96, $61, $E5, $C1, $69, $B8, $AF, $F8, $0E, $05,
    $16, $A5, $9F, $0A, $3D, $D7, $04, $1E, $4F, $4C, $24, $A9, $80, $D5, $40, $00,
    $F9, $FA, $19, $C0, $C5, $17, $9A, $0B, $B7, $C9, $39, $7D, $2B, $A1, $86, $7F,
    $EF, $EC, $D0, $BC, $4D, $CD, $2E, $CF, $15, $06, $0F, $66, $E7, $FB, $6E, $23,
    $35, $52, $FE, $FC, $FD, $EE, $C6, $30, $77, $E6, $1C, $0C, $FF, $25, $89, $36,
    $C2, $8C, $73, $10, $D8, $49, $D3, $94, $A7, $B2, $62, $26, $D1, $3F, $BB, $B9,
    $3B, $38, $DB, $14, $9E, $83, $9D, $1F, $82, $A0, $5C, $48, $72, $34, $4E, $41,
    $57, $E9, $7C, $2D, $A2, $E4, $20, $7B, $B3, $07, $0D, $90, $E2, $4A, $60, $45), (
    $F4, $8A, $D0, $58, $E4, $26, $1B, $55, $92, $94, $54, $5D, $75, $82, $C9, $7F,
    $02, $17, $0B, $73, $6C, $9D, $15, $E5, $CB, $7E, $12, $E6, $1C, $E7, $37, $81,
    $22, $D9, $3E, $E8, $0A, $97, $38, $5A, $13, $78, $03, $4A, $7C, $B0, $1A, $E9,
    $CD, $49, $DC, $AB, $EA, $27, $14, $A1, $0E, $C0, $B6, $25, $5C, $8D, $2B, $24,
    $39, $1F, $05, $72, $B7, $C5, $3C, $6E, $D3, $64, $3F, $B4, $59, $5E, $EB, $20,
    $EC, $F6, $BA, $6A, $60, $D1, $5F, $CE, $A2, $F2, $F1, $8E, $11, $34, $CC, $41,
    $A6, $89, $FA, $7A, $AF, $87, $9E, $0F, $53, $6B, $56, $D5, $E0, $99, $42, $8C,
    $DF, $B8, $63, $62, $7D, $DB, $DE, $43, $DA, $04, $2C, $31, $52, $47, $BF, $8B,
    $FC, $FB, $D4, $09, $76, $07, $98, $90, $E3, $BE, $9C, $D8, $06, $01, $EE, $C4,
    $DD, $A7, $CA, $4F, $C3, $A9, $FE, $85, $B1, $4C, $9B, $6D, $28, $4E, $BC, $0D,
    $AE, $29, $51, $50, $BB, $18, $74, $79, $65, $96, $CF, $EF, $F3, $B3, $9A, $23,
    $C1, $2F, $10, $A8, $AA, $66, $C7, $16, $93, $4B, $F7, $86, $67, $A3, $3D, $3B,
    $6F, $84, $71, $88, $69, $57, $E2, $A0, $5B, $F5, $91, $C8, $95, $2D, $80, $61,
    $46, $F9, $19, $C2, $D2, $7B, $D7, $AD, $F0, $08, $2A, $E1, $A5, $A4, $44, $83,
    $70, $D6, $77, $32, $FD, $1E, $C6, $BD, $45, $0C, $9F, $B2, $AC, $36, $40, $00,
    $FF, $68, $2E, $4D, $21, $33, $48, $F8, $B9, $3A, $30, $B5, $8F, $1D, $35, $ED), (
    $EE, $1A, $7F, $D1, $B7, $74, $42, $BC, $77, $20, $D5, $EB, $BD, $E6, $A3, $A6,
    $A0, $65, $85, $CF, $29, $30, $BF, $73, $A4, $F3, $52, $4F, $76, $D0, $E5, $E4,
    $3D, $3B, $6B, $69, $2E, $F6, $2C, $CA, $1F, $25, $ED, $59, $58, $36, $1D, $F7,
    $37, $C4, $61, $43, $4A, $8E, $1C, $5A, $5D, $F0, $16, $7E, $EA, $75, $19, $AD,
    $C3, $70, $F1, $17, $06, $93, $57, $F8, $CE, $C7, $0C, $0F, $7A, $09, $3C, $08,
    $27, $86, $56, $9B, $C5, $B1, $0D, $F9, $10, $55, $3F, $7C, $A1, $54, $68, $BE,
    $8C, $F5, $8A, $C1, $FA, $91, $9C, $22, $66, $D7, $E3, $32, $07, $94, $40, $EC,
    $8B, $41, $87, $F4, $44, $CB, $A9, $BB, $2A, $28, $CC, $33, $6C, $EF, $82, $B9,
    $79, $C0, $B2, $78, $D6, $47, $BA, $35, $00, $3A, $04, $63, $90, $39, $95, $FB,
    $C8, $6D, $0B, $50, $DE, $5E, $34, $2B, $9A, $8F, $5F, $38, $2D, $7D, $E2, $46,
    $4E, $24, $DF, $DC, $0E, $FC, $AB, $03, $A5, $97, $AA, $B4, $1B, $2F, $9E, $62,
    $A7, $4D, $67, $9F, $DD, $C6, $B5, $02, $DA, $D9, $84, $F2, $60, $48, $4C, $92,
    $DB, $81, $6F, $21, $80, $B8, $D8, $C2, $3E, $B3, $98, $5B, $E9, $CD, $05, $51,
    $B6, $D3, $7B, $23, $9D, $11, $AE, $E0, $6A, $D2, $64, $4B, $E7, $96, $26, $01,
    $53, $FD, $45, $E8, $6E, $89, $D4, $B0, $13, $31, $8D, $49, $A8, $72, $71, $18,
    $99, $FE, $1E, $83, $15, $AC, $AF, $A2, $14, $E1, $FF, $5C, $12, $0A, $88, $C9), (
    $23, $94, $5B, $51, $CE, $D2, $E0, $05, $A7, $06, $4D, $B2, $6E, $95, $AF, $29,
    $BA, $13, $E1, $E2, $5E, $B6, $E5, $4A, $50, $F5, $43, $26, $B5, $18, $83, $22,
    $57, $2F, $8C, $A3, $5F, $89, $04, $D3, $0A, $C2, $FA, $C0, $2A, $74, $37, $DA,
    $45, $D4, $0F, $77, $27, $3D, $C6, $53, $CC, $DF, $A6, $9F, $9D, $C8, $E7, $2E,
    $1A, $F6, $DE, $F1, $7C, $15, $0E, $47, $62, $52, $5C, $7D, $41, $2D, $E8, $D8,
    $4C, $A8, $DC, $71, $FC, $1C, $FD, $4F, $CB, $E3, $72, $BD, $1F, $7F, $D9, $09,
    $B8, $00, $1B, $75, $0C, $59, $16, $92, $6B, $3F, $93, $97, $F8, $CF, $30, $A5,
    $02, $3B, $11, $66, $BC, $60, $25, $ED, $28, $EF, $61, $D7, $F9, $DD, $86, $C3,
    $48, $73, $90, $32, $AC, $5A, $F3, $AD, $40, $F0, $88, $08, $B4, $19, $9E, $33,
    $49, $0D, $EA, $CD, $20, $79, $FB, $2C, $65, $17, $12, $35, $84, $87, $36, $BE,
    $B1, $63, $24, $C9, $3C, $4B, $AE, $EB, $8B, $9B, $98, $6C, $9A, $F2, $80, $D1,
    $34, $8A, $C1, $6D, $82, $D0, $DB, $7E, $8E, $B9, $31, $1E, $7A, $44, $E9, $91,
    $14, $01, $68, $4E, $39, $A4, $AA, $46, $A2, $96, $99, $58, $64, $E6, $56, $D5,
    $8F, $CA, $6F, $76, $54, $03, $AB, $E4, $3E, $8D, $5D, $42, $85, $9C, $78, $F4,
    $10, $B7, $B3, $D6, $A9, $0B, $21, $6A, $BB, $C4, $EE, $07, $81, $BF, $1D, $FE,
    $38, $FF, $7B, $EC, $C7, $A0, $2B, $C5, $55, $A1, $69, $B0, $70, $67, $F7, $3A), (
    $6D, $5E, $46, $E1, $06, $E2, $1F, $7C, $38, $01, $B6, $A9, $26, $CD, $97, $82,
    $E3, $CC, $B3, $67, $E4, $70, $48, $D4, $8A, $C2, $35, $83, $7A, $99, $C7, $22,
    $9D, $37, $B4, $64, $58, $AB, $95, $7F, $18, $8C, $E5, $68, $5F, $B9, $71, $0D,
    $D5, $72, $E6, $20, $69, $F5, $3A, $45, $9F, $28, $D7, $F1, $2C, $62, $D9, $91,
    $A7, $1C, $BC, $9B, $B0, $73, $60, $F9, $EE, $AE, $59, $04, $24, $B5, $BE, $36,
    $2B, $33, $93, $B7, $17, $4C, $FB, $A0, $65, $40, $D0, $85, $A1, $E9, $92, $5B,
    $C0, $50, $66, $53, $15, $21, $DD, $5C, $6F, $E7, $3C, $B2, $49, $B8, $05, $CA,
    $6E, $C5, $F2, $2E, $D6, $7B, $09, $88, $C6, $A4, $BA, $8B, $2A, $A6, $3F, $BF,
    $23, $76, $3D, $11, $DC, $EB, $3E, $E0, $DA, $F6, $F8, $3B, $CE, $94, $6B, $0A,
    $29, $2F, $30, $9A, $A2, $41, $12, $5A, $51, $00, $DF, $19, $E8, $EA, $1B, $61,
    $63, $96, $31, $79, $74, $98, $A3, $0C, $39, $10, $B1, $ED, $CB, $C8, $F3, $C3,
    $4A, $47, $1A, $16, $DE, $43, $27, $9C, $2D, $4D, $56, $84, $AD, $AF, $90, $D8,
    $FA, $CF, $57, $BD, $FD, $32, $54, $34, $13, $4B, $C9, $80, $D3, $1E, $81, $87,
    $07, $6C, $6A, $DB, $52, $8F, $42, $C4, $0F, $89, $7E, $FE, $AA, $F4, $4E, $1D,
    $25, $EF, $D2, $03, $FF, $F7, $EC, $D1, $C1, $A5, $0B, $0E, $75, $5D, $02, $8D,
    $7D, $9E, $86, $78, $77, $4F, $08, $14, $BB, $A8, $F0, $8E, $44, $AC, $55, $FC), (
    $E9, $E1, $07, $AD, $E2, $F8, $F5, $B7, $FC, $49, $13, $48, $D9, $E5, $DE, $87,
    $42, $99, $11, $01, $91, $E3, $43, $3B, $EA, $09, $50, $F7, $33, $C3, $A3, $73,
    $D8, $39, $E8, $E4, $80, $F6, $96, $D3, $6A, $98, $FB, $EF, $2E, $1D, $0D, $81,
    $54, $20, $E6, $9E, $1E, $72, $1A, $C7, $40, $C0, $88, $9F, $FD, $7D, $A1, $D2,
    $92, $84, $4E, $9B, $51, $F0, $68, $8F, $70, $FA, $9A, $EB, $FF, $94, $A6, $12,
    $57, $BC, $04, $0C, $4B, $63, $21, $3C, $95, $02, $2C, $90, $F2, $79, $F3, $E0,
    $CF, $A8, $23, $15, $3D, $37, $52, $CB, $18, $B6, $47, $53, $CA, $41, $60, $6C,
    $D1, $26, $65, $55, $6E, $3F, $7C, $9C, $B1, $F4, $AC, $D6, $56, $34, $8E, $A5,
    $0F, $00, $BA, $D5, $66, $D4, $DC, $0B, $A2, $C1, $67, $F1, $2B, $2F, $7E, $85,
    $30, $32, $03, $BB, $4A, $4F, $C9, $86, $ED, $58, $16, $14, $62, $59, $5A, $B2,
    $AE, $C4, $46, $61, $24, $A0, $6B, $7A, $EC, $5B, $7B, $B5, $76, $5F, $6D, $DF,
    $29, $D0, $3E, $2A, $CD, $A4, $31, $08, $DA, $8A, $B0, $71, $CE, $8D, $4D, $06,
    $4C, $AF, $FE, $97, $5D, $36, $D7, $C5, $1C, $44, $F9, $19, $75, $C8, $DB, $10,
    $7F, $77, $69, $1F, $25, $CC, $BD, $74, $2D, $8C, $AA, $28, $83, $78, $8B, $89,
    $A7, $C2, $5E, $17, $05, $45, $AB, $35, $B4, $B9, $B3, $82, $1B, $27, $64, $9D,
    $38, $BE, $0E, $6F, $22, $E7, $DD, $C6, $A9, $B8, $3A, $5C, $93, $0A, $EE, $BF), (
    $5F, $A5, $04, $60, $09, $3E, $57, $23, $D8, $9A, $1C, $B6, $C3, $F6, $DE, $03,
    $59, $13, $B2, $85, $A7, $FA, $48, $10, $15, $2E, $93, $A4, $14, $F9, $77, $FB,
    $9D, $3F, $D9, $9C, $7B, $50, $A3, $3B, $3A, $62, $29, $49, $A2, $74, $F1, $E3,
    $75, $33, $F4, $43, $2A, $6C, $D1, $0A, $82, $AE, $B3, $4E, $F8, $D7, $1F, $B4,
    $AB, $00, $AA, $6D, $B9, $C7, $C6, $07, $7F, $20, $80, $EF, $0B, $45, $E9, $ED,
    $1B, $36, $E5, $68, $8C, $9E, $A9, $7A, $19, $1D, $BB, $11, $78, $6E, $84, $5D,
    $EA, $6B, $86, $C1, $DF, $4D, $90, $4B, $C9, $CE, $54, $FC, $17, $95, $52, $05,
    $D6, $69, $53, $FD, $A1, $CF, $D0, $CB, $41, $D3, $7D, $BF, $2D, $47, $6A, $02,
    $8D, $8F, $28, $64, $F0, $BA, $E6, $1A, $79, $E0, $EB, $8B, $EC, $B0, $C5, $3C,
    $21, $D5, $66, $A8, $9F, $DA, $16, $E4, $81, $D2, $F7, $CD, $30, $C2, $FE, $4A,
    $87, $F3, $72, $0D, $71, $91, $44, $67, $3D, $65, $37, $B5, $F2, $5A, $27, $18,
    $DB, $C0, $EE, $C4, $DD, $A0, $0F, $40, $6F, $AD, $8E, $4F, $0E, $CA, $32, $A6,
    $2F, $58, $56, $51, $06, $99, $9B, $8A, $2B, $E2, $83, $94, $E8, $26, $5C, $4C,
    $96, $31, $FF, $AC, $70, $88, $35, $25, $E7, $08, $BD, $BC, $76, $55, $46, $22,
    $2C, $7E, $7C, $97, $12, $B1, $F5, $34, $42, $1E, $61, $01, $5B, $B7, $38, $0C,
    $E1, $24, $73, $39, $DC, $92, $5E, $98, $C8, $89, $CC, $BE, $B8, $D4, $AF, $63), (
    $09, $5E, $2D, $7A, $DB, $59, $E4, $19, $C5, $A3, $3A, $5A, $43, $C9, $5B, $D5,
    $42, $75, $13, $97, $E1, $65, $77, $95, $5F, $41, $A6, $B6, $17, $32, $79, $10,
    $70, $7C, $D8, $06, $8A, $1C, $BE, $DF, $E6, $39, $57, $F7, $91, $5C, $88, $D7,
    $33, $63, $15, $8E, $53, $34, $D2, $F6, $7E, $2C, $05, $AF, $AE, $BC, $86, $47,
    $99, $93, $C1, $46, $4B, $73, $3F, $20, $6E, $CD, $52, $23, $FA, $71, $85, $D4,
    $9B, $31, $BD, $25, $90, $72, $2E, $48, $F5, $6B, $1A, $F4, $03, $F3, $30, $36,
    $F0, $A4, $D1, $58, $E5, $1D, $76, $3E, $D3, $6D, $2A, $E7, $12, $50, $6F, $F9,
    $22, $FB, $C7, $EC, $49, $EE, $3B, $8D, $08, $4C, $BA, $E3, $35, $ED, $F2, $C2,
    $E8, $2F, $B2, $B4, $AC, $F1, $FC, $EB, $14, $A8, $74, $7F, $EF, $54, $AD, $B3,
    $02, $6C, $2B, $27, $64, $BB, $40, $EA, $FD, $A0, $7D, $BF, $B8, $DA, $C4, $44,
    $96, $B5, $E9, $9C, $B0, $AB, $E2, $CE, $DE, $37, $66, $29, $C6, $A5, $CA, $A7,
    $B1, $7B, $DD, $0F, $84, $01, $D0, $1E, $0C, $FE, $4E, $D9, $DC, $94, $00, $38,
    $B9, $45, $1B, $69, $C0, $8C, $92, $D6, $18, $04, $A9, $81, $5D, $21, $1F, $9E,
    $98, $A2, $83, $87, $60, $55, $80, $CF, $56, $C8, $3C, $26, $3D, $A1, $FF, $07,
    $F8, $68, $8F, $E0, $4F, $B7, $6A, $0B, $16, $62, $61, $AA, $9D, $0D, $89, $28,
    $9A, $0A, $82, $4A, $C3, $78, $11, $4D, $67, $51, $CC, $0E, $24, $CB, $8B, $9F));

  //RE-ORDERING MATRIX
  P0: array[0..15, 0..15] of longword = (
    ($A, $3, $B, $C, $5, $E, $9, $F, $0, $7, $4, $6, $1, $D, $2, $8),
    ($9, $5, $F, $3, $1, $0, $A, $4, $7, $B, $E, $8, $2, $6, $D, $C),
    ($6, $D, $A, $4, $3, $5, $2, $8, $B, $F, $9, $C, $0, $E, $7, $1),
    ($E, $7, $0, $D, $8, $B, $1, $3, $9, $6, $C, $4, $A, $2, $F, $5),
    ($C, $A, $2, $5, $F, $D, $7, $9, $4, $E, $6, $B, $8, $3, $1, $0),
    ($5, $9, $3, $8, $D, $6, $4, $C, $1, $0, $7, $2, $E, $B, $A, $F),
    ($0, $6, $4, $A, $7, $3, $B, $E, $2, $8, $5, $1, $D, $F, $C, $9),
    ($D, $F, $9, $0, $6, $2, $3, $1, $E, $C, $A, $5, $B, $8, $4, $7),
    ($1, $0, $C, $2, $9, $7, $6, $D, $3, $5, $8, $E, $F, $A, $B, $4),
    ($3, $8, $5, $7, $2, $C, $E, $B, $A, $9, $D, $F, $4, $1, $0, $6),
    ($F, $B, $D, $1, $C, $8, $0, $6, $5, $2, $3, $7, $9, $4, $E, $A),
    ($8, $E, $1, $9, $4, $F, $C, $5, $6, $D, $2, $A, $7, $0, $3, $B),
    ($4, $C, $7, $6, $E, $1, $5, $2, $F, $A, $B, $0, $3, $9, $8, $D),
    ($7, $2, $6, $B, $0, $4, $D, $A, $8, $1, $F, $3, $5, $C, $9, $E),
    ($2, $1, $8, $E, $B, $A, $F, $7, $D, $4, $0, $9, $C, $5, $6, $3),
    ($B, $4, $E, $F, $A, $9, $8, $0, $C, $3, $1, $D, $6, $7, $5, $2));

  //RE-ORDERING MATRIX INVERSE
  P1: array[0..15, 0..15] of longword = (
    ($8, $C, $E, $1, $A, $4, $B, $9, $F, $6, $0, $2, $3, $D, $5, $7),
    ($5, $4, $C, $3, $7, $1, $D, $8, $B, $0, $6, $9, $F, $E, $A, $2),
    ($C, $F, $6, $4, $3, $5, $0, $E, $7, $A, $2, $8, $B, $1, $D, $9),
    ($2, $6, $D, $7, $B, $F, $9, $1, $4, $8, $C, $5, $A, $3, $0, $E),
    ($F, $E, $2, $D, $8, $3, $A, $6, $C, $7, $1, $B, $0, $5, $9, $4),
    ($9, $8, $B, $2, $6, $0, $5, $A, $3, $1, $E, $D, $7, $4, $C, $F),
    ($0, $B, $8, $5, $2, $A, $1, $4, $9, $F, $3, $6, $E, $C, $7, $D),
    ($3, $7, $5, $6, $E, $B, $4, $F, $D, $2, $A, $C, $9, $0, $8, $1),
    ($1, $0, $3, $8, $F, $9, $6, $5, $A, $4, $D, $E, $2, $7, $B, $C),
    ($E, $D, $4, $0, $C, $2, $F, $3, $1, $9, $8, $7, $5, $A, $6, $B),
    ($6, $3, $9, $A, $D, $8, $7, $B, $5, $C, $F, $1, $4, $2, $E, $0),
    ($D, $2, $A, $E, $4, $7, $8, $C, $0, $3, $B, $F, $6, $9, $1, $5),
    ($B, $5, $7, $C, $0, $6, $3, $2, $E, $D, $9, $A, $1, $F, $4, $8),
    ($4, $9, $1, $B, $5, $C, $2, $0, $8, $E, $7, $3, $D, $6, $F, $A),
    ($A, $1, $0, $F, $9, $D, $E, $7, $2, $B, $5, $4, $C, $8, $3, $6),
    ($7, $A, $F, $9, $1, $E, $C, $D, $6, $5, $4, $0, $8, $B, $2, $3));

function Mul(const Factor1, Factor2: longword): longword;
var
  Product: Int64;
  Lhalf, Rhalf: longword;
begin
  Product := Factor1 * Factor2;
  if Product = 0 then
    Result := 1 - Factor1 - Factor2
  else
  begin
    Lhalf := Product shr 32;
    Rhalf := Product and $FFFFFFFF;
    Result := Rhalf - Lhalf;
    if Rhalf < Lhalf then
      Inc(Result);
  end;
end;

procedure BravionEncrypt(var Context: TBravionContext; var B: TBravionBlock32);
var
  Temp: array[0..15] of longword;
  pB: ^TBravionBlock8;
  CarryBit: longword;
  i: integer;
begin
  pB := @B;
  with Context do
  begin
    //ALGORITHM PERMUTATION
    B[0] := B[0] xor RK[PK[16], 0];
    B[1] := B[1] xor RK[PK[17], 1];
    B[2] := B[2] xor RK[PK[18], 2];
    B[3] := B[3] xor RK[PK[19], 3];

    for i := 0 to 15 do //16 ROUNDS
    begin
      //IRRATIONALIZE 8BIT GROUPS
      CarryBit := (B[0] and 2147483648) shr 31;
      B[0] := (B[0] shl 1) or ((B[1] and 2147483648) shr 31);
      B[1] := (B[1] shl 1) or ((B[2] and 2147483648) shr 31);
      B[2] := (B[2] shl 1) or ((B[3] and 2147483648) shr 31);
      B[3] := (B[3] shl 1) or CarryBit;

      //PERMUTATION
      B[3] := B[3] xor (B[2] - RK[i, 3]);
      B[2] := B[2] xor Mul(B[1], RK[i, 2]);
      B[1] := B[1] xor (B[0] + RK[i, 1]);
      B[0] := B[0] xor RK[i, 0];

      //SUBSTITUTION
{if anyone can optimize the following 20 lines please post it as a comment.
Bellow may seem slow, but it's MUCH faster than using Temp as a byte array
and Move(Temp,B,16). This is probably because the compiler is optimized for 32bit integers. An assembly version would be VERY fast.}
      Temp[0] := S0[i, pB^[P0[PK[i], 0]]];
      Temp[1] := S0[i, pB^[P0[PK[i], 1]]];
      Temp[2] := S0[i, pB^[P0[PK[i], 2]]];
      Temp[3] := S0[i, pB^[P0[PK[i], 3]]];
      Temp[4] := S0[i, pB^[P0[PK[i], 4]]];
      Temp[5] := S0[i, pB^[P0[PK[i], 5]]];
      Temp[6] := S0[i, pB^[P0[PK[i], 6]]];
      Temp[7] := S0[i, pB^[P0[PK[i], 7]]];
      Temp[8] := S0[i, pB^[P0[PK[i], 8]]];
      Temp[9] := S0[i, pB^[P0[PK[i], 9]]];
      Temp[10] := S0[i, pB^[P0[PK[i], 10]]];
      Temp[11] := S0[i, pB^[P0[PK[i], 11]]];
      Temp[12] := S0[i, pB^[P0[PK[i], 12]]];
      Temp[13] := S0[i, pB^[P0[PK[i], 13]]];
      Temp[14] := S0[i, pB^[P0[PK[i], 14]]];
      Temp[15] := S0[i, pB^[P0[PK[i], 15]]];
      B[0] := (Temp[3] shl 24) or (Temp[2] shl 16) or (Temp[1] shl 8) or Temp[0];
      B[1] := (Temp[7] shl 24) or (Temp[6] shl 16) or (Temp[5] shl 8) or Temp[4];
      B[2] := (Temp[11] shl 24) or (Temp[10] shl 16) or (Temp[9] shl 8) or Temp[8];
      B[3] := (Temp[15] shl 24) or (Temp[14] shl 16) or (Temp[13] shl 8) or Temp[12];
    end;

    //ALGORITHM PERMUTATION
    B[0] := B[0] xor RK[PK[20], 0];
    B[1] := B[1] xor RK[PK[21], 1];
    B[2] := B[2] xor RK[PK[22], 2];
    B[3] := B[3] xor RK[PK[23], 3];
  end;
end;

procedure BravionDecrypt(var Context: TBravionContext; var B: TBravionBlock32);
var
  Temp: array[0..15] of longword;
  pB: ^TBravionBlock8;
  CarryBit: longword;
  i: integer;
begin
  pB := @B;
  with Context do
  begin
    B[3] := B[3] xor RK[PK[23], 3];
    B[2] := B[2] xor RK[PK[22], 2];
    B[1] := B[1] xor RK[PK[21], 1];
    B[0] := B[0] xor RK[PK[20], 0];

    for i := 15 downto 0 do
    begin
      Temp[0] := S1[i, pB^[P1[PK[i], 0]]];
      Temp[1] := S1[i, pB^[P1[PK[i], 1]]];
      Temp[2] := S1[i, pB^[P1[PK[i], 2]]];
      Temp[3] := S1[i, pB^[P1[PK[i], 3]]];
      Temp[4] := S1[i, pB^[P1[PK[i], 4]]];
      Temp[5] := S1[i, pB^[P1[PK[i], 5]]];
      Temp[6] := S1[i, pB^[P1[PK[i], 6]]];
      Temp[7] := S1[i, pB^[P1[PK[i], 7]]];
      Temp[8] := S1[i, pB^[P1[PK[i], 8]]];
      Temp[9] := S1[i, pB^[P1[PK[i], 9]]];
      Temp[10] := S1[i, pB^[P1[PK[i], 10]]];
      Temp[11] := S1[i, pB^[P1[PK[i], 11]]];
      Temp[12] := S1[i, pB^[P1[PK[i], 12]]];
      Temp[13] := S1[i, pB^[P1[PK[i], 13]]];
      Temp[14] := S1[i, pB^[P1[PK[i], 14]]];
      Temp[15] := S1[i, pB^[P1[PK[i], 15]]];
      B[0] := (Temp[3] shl 24) or (Temp[2] shl 16) or (Temp[1] shl 8) or Temp[0];
      B[1] := (Temp[7] shl 24) or (Temp[6] shl 16) or (Temp[5] shl 8) or Temp[4];
      B[2] := (Temp[11] shl 24) or (Temp[10] shl 16) or (Temp[9] shl 8) or Temp[8];
      B[3] := (Temp[15] shl 24) or (Temp[14] shl 16) or (Temp[13] shl 8) or Temp[12];

      B[0] := B[0] xor RK[i, 0];
      B[1] := B[1] xor (B[0] + RK[i, 1]);
      B[2] := B[2] xor Mul(B[1], RK[i, 2]);
      B[3] := B[3] xor (B[2] - RK[i, 3]);

      CarryBit := (B[3] and 1) shl 31;
      B[3] := (B[3] shr 1) or ((B[2] and 1) shl 31);
      B[2] := (B[2] shr 1) or ((B[1] and 1) shl 31);
      B[1] := (B[1] shr 1) or ((B[0] and 1) shl 31);
      B[0] := (B[0] shr 1) or CarryBit;
    end;

    B[3] := B[3] xor RK[PK[19], 3];
    B[2] := B[2] xor RK[PK[18], 2];
    B[1] := B[1] xor RK[PK[17], 1];
    B[0] := B[0] xor RK[PK[16], 0];
  end;
end;

procedure BravionInit(var Context: TBravionContext; var Key: TBravionKey32);
const
  M1 = longword(259200);
  M2 = longword(134456);
  M3 = longword(243000);
  I1 = longword(7141);
  I2 = longword(8121);
  I3 = longword(4561);
  C1 = longword(54773);
  C2 = longword(28411);
  C3 = longword(51349);

var
  X1, X2, X3: longword;
  R: array[1..97] of real;
  Temp: TBravionBlock32;
  i, j, k: integer;
begin
  with Context do
  begin
    FillChar(PK, Sizeof(TBravionPathKey8), 0);
    FillChar(RK, Sizeof(TBravionRoundKey32), 0);
    i := 0;
    repeat //KEY EXPANSION
      {I'm actualy using a PRNG with 2^32 period for the expansion}
      X1 := (Key[i] + C1) mod M1;
      X1 := (X1 * I1 + C1) mod M1;
      X2 := X1 mod M2;
      X1 := (X1 * I1 + C1) mod M1;
      X3 := X1 mod M3;
      for j := 1 to 97 do
      begin
        X1 := (X1 * I1 + C1) mod M1;
        X2 := (X2 * I2 + C2) mod M2;
        R[j] := (X1 + X2 / M2) / M1;
      end;

      for j := 0 to 3 do
      begin
        X1 := (X1 * I1 + C1) mod M1;
        X2 := (X2 * I2 + C2) mod M2;
        X3 := (X3 * I3 + C3) mod M3;
        k := 1 + (97 * X3) div M3;
        RK[i * 2, j] := trunc($FFFFFFFF * R[k]);
        R[k] := (X1 + X2 / M2) / M1;

        X1 := (X1 * I1 + C1) mod M1;
        X2 := (X2 * I2 + C2) mod M2;
        X3 := (X3 * I3 + C3) mod M3;
        k := 1 + (97 * X3) div M3;
        RK[(i * 2) + 1, j] := trunc($FFFFFFFF * r[k]);
        R[k] := (X1 + X2 / M2) / M1;
      end;
      Inc(i, 1);
    until i = 8;

    for i := 0 to 15 do //SET 4BIT PATH KEYS
    begin
      PK[i] := (TBravionKey8(Key)[i] xor TBravionKey8(Key)[i + 16]) and $F;
      j := 16 + (i and 7);
      PK[j] := PK[j] xor ((TBravionKey8(Key)[i] xor TBravionKey8(Key)[i + 16]) and $F0)
        shr 4;
    end;
  end;

  for i := 0 to 127 do //PERMUTE ROUND KEYS
  begin
    j := 0;
    repeat
      Move(Key[0], Temp, Sizeof(TBravionBlock32));
      BravionEncrypt(Context, Temp);
      Move(Temp, Context.RK[j], Sizeof(TBravionBlock32));

      Move(Key[4], Temp, Sizeof(TBravionBlock32));
      BravionEncrypt(Context, Temp);
      Move(Temp, Context.RK[j + 1], Sizeof(TBravionBlock32));
      Inc(j, 2);
    until j = 16;
  end;
end;

end.

Using the encryption is very simple:

procedure TForm1.Button1Click(Sender: TObject);
var
  k: TBravionKey32;
  b: TBravionBlock32;
  c: TBravionContext;
  s: string;
  i: longword;
begin
  randomize;
  for i := 0 to 7 do
    k[i] := Random(MaxInt);
  for i := 0 to 3 do
    b[i] := Random(MaxInt);
  BravionInit(c, k);

  s := 'Key: {';
  for i := 0 to 15 do
    s := s + inttohex(TBravionKey8(k)[i], 2);
  memo1.lines.add(s + ',');

  s := '         ';
  for i := 16 to 31 do
    s := s + inttohex(TBravionKey8(k)[i], 2);
  memo1.lines.add(s + '}');

  s := 'Plaintext:    {';
  for i := 0 to 15 do
    s := s + inttohex(TBravionBlock8(b)[i], 2);
  memo1.lines.add(s + '}');

  BravionEncrypt(c, b);
  s := 'Ciphertext: {';
  for i := 0 to 15 do
    s := s + inttohex(TBravionBlock8(b)[i], 2);
  memo1.lines.add(s + '}');

  BravionDecrypt(c, b);
  s := 'Plaintext:    {';
  for i := 0 to 15 do
    s := s + inttohex(TBravionBlock8(b)[i], 2);
  memo1.lines.add(s + '}');
  memo1.lines.add('');
end;

this example requires a form, button and memo. it's pretty self explanatory.