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 13., hétfő
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;
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.
2009. április 10., péntek
How to use True Type fonts without installing
Problem/Question/Abstract:
How to use True Type fonts without installing
Answer:
Setting an alternative font for your forms is easy. But how to use your specialized fonts without the need to fill up your user's FONTS directory? Well, it's just a few lines, so here we go:
// first load it in the OnCreate event of a form:
procedure TForm1.FormCreate(Sender: TObject);
begin
AddFontResource('c:\FONTS\MyFont.TTF');
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
end;
// before application terminates, we must free it:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
RemoveFontResource('C:\FONTS\MyFont.TTF');
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
end;
2009. április 9., csütörtök
Save and retrieve a file to/ from a blob field
Problem/Question/Abstract:
How can I save a file in an Access database. I would like to save zip files in an Access mdb database. (OLE OBJECT Field) BLOB FIELD
Answer:
Solve 1:
Here's a unit that demonstrates getting a file to/ from a blob field:
unit FileToFromDB;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, FileCtrl, DBCtrls, ExtCtrls, Db, DBTables, Menus;
type
TFrmFileToFromDB = class(TForm)
CbxDriveSelect: TDriveComboBox;
LbxDirSelect: TDirectoryListBox;
LbxFileSelect: TFileListBox;
BtnToDB: TButton;
DataSource1: TDataSource;
Table1: TTable;
Table1TheLongInt: TIntegerField;
Table1ABlobField: TBlobField;
Table1Bytes1: TBlobField;
Table1Bytes2: TBytesField;
Table1B32_1: TBlobField;
Table1B32_2: TBytesField;
DBNavigator1: TDBNavigator;
BtnFromDB: TButton;
Memo1: TMemo;
LblCopyright: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure BtnToDBClick(Sender: TObject);
procedure BtnFromDBClick(Sender: TObject);
procedure LbxFileSelectChange(Sender: TObject);
procedure DataSource1DataChange(Sender: TObject; Field: TField);
private
{ Private declarations }
public
{ Public declarations }
end;
var
FrmFileToFromDB: TFrmFileToFromDB;
implementation
{$R *.DFM}
procedure TFrmFileToFromDB.FormCreate(Sender: TObject);
begin
Table1.Open;
Memo1.Clear;
end;
procedure TFrmFileToFromDB.FormDestroy(Sender: TObject);
begin
Table1.Close;
end;
procedure TFrmFileToFromDB.BtnToDBClick(Sender: TObject);
var
curNdx: Integer;
f: Integer;
theBlobStream: TBlobStream;
thisFile: TFileStream;
begin
curNdx := LbxFileSelect.ItemIndex;
LbxFileSelect.Items.BeginUpdate;
try
for f := 0 to LbxFileSelect.Items.Count - 1 do
begin
if LbxFileSelect.Selected[f] then
begin
LbxFileSelect.ItemIndex := f;
Table1.Edit;
theBlobStream := TBlobStream.Create(Table1B32_1, bmReadWrite);
try
thisFile := TFileStream.Create(LbxFileSelect.Filename, fmOpenRead);
try
theBlobStream.CopyFrom(thisFile, thisFile.Size);
finally
thisFile.Free;
end;
finally
theBlobStream.Free;
end;
Table1.Post;
Table1.Next;
end;
end;
Table1.First;
finally
LbxFileSelect.ItemIndex := curNdx;
LbxFileSelect.Items.EndUpdate;
end;
end;
procedure TFrmFileToFromDB.BtnFromDBClick(Sender: TObject);
var
hdr: array[1..3] of byte;
thisFile: TMemoryStream;
thisText: TMemoryStream;
theBlobStream: TBlobStream;
begin
thisFile := TMemoryStream.Create;
Memo1.Clear;
try
theBlobStream := TBlobStream.Create(TBlobField(Table1.FieldByName('B32_1')), bmRead);
try
thisFile.CopyFrom(theBlobStream, theBlobStream.Size);
thisFile.Seek(0, soFromBeginning);
finally
theBlobStream.Free;
end;
thisFile.Read(hdr[1], 3);
thisFile.Seek(0, soFromBeginning);
if (hdr[1] = $FF) and (hdr[2] = $0A) and (hdr[3] = $0) then
begin
thisText := TMemoryStream.Create;
try
try
ObjectResourceToText(thisFile, thisText); {DFM to text.}
thisText.Seek(0, soFromBeginning); {Text stream to beginning}
Memo1.Lines.LoadFromStream(thisText); {Text to memo1}
except
Memo1.Lines.Add('Invalid DFM image');
end;
finally
thisText.Free;
end
end
else
begin
Memo1.Lines.Add('Invalid DFM image');
end;
finally
thisFile.Free;
end;
end;
procedure TFrmFileToFromDB.LbxFileSelectChange(Sender: TObject);
begin
BtnToDB.Enabled := LbxFileSelect.SelCount > 0;
end;
procedure TFrmFileToFromDB.DataSource1DataChange(Sender: TObject; Field: TField);
begin
BtnFromDB.Click;
end;
end.
Solve 2:
If you develop a database related software, then very popular task is to save some files (documents/images/reports/etc) in some BLOB field of table and use these saved data later.
In this tip I want to show how this task could be solved.
To save a file to BLOB:
blob := yourDataset.CreateBlobStream(yourDataset.FieldByName('YOUR_BLOB'),
bmWrite);
try
blob.Seek(0, soFromBeginning);
fs := TFileStream.Create('c:\your_name.doc', fmOpenRead or
fmShareDenyWrite);
try
blob.CopyFrom(fs, fs.Size)
finally
fs.Free
end;
finally
blob.Free
end;
to load from BLOB:
blob := yourDataset.CreateBlobStream(yourDataset.FieldByName('YOUR_BLOB'),
bmRead);
try
blob.Seek(0, soFromBeginning);
with TFileStream.Create('c:\your_name.doc', fmCreate) do
try
CopyFrom(blob, blob.Size)
finally
Free
end;
finally
blob.Free
end;
Using this code you can work with any database engine (BDE/ADO/DAO/ODBC/etc) and any file format (document of MS Word, spreadsheet of MS Excel, bitmap or jpeg pictures, wav-files etc)
2009. április 8., szerda
How to change the print orientation after BeginDoc and before EndDoc
Problem/Question/Abstract:
I want to change the print orientation and use printer.newpage to make just one job to print several pages.
Answer:
procedure TForm1.Button2Click(Sender: TObject);
var
Device: array[0..255] of char;
Driver: array[0..255] of char;
Port: array[0..255] of char;
hDeviceMode: THandle;
pDevMode: PDeviceMode;
begin
with Printer do
begin
BeginDoc;
try
Canvas.font.size := 20;
Canvas.font.name := 'Arial';
Canvas.TextOut(50, 50, 'This is portrait');
GetPrinter(Device, Driver, Port, hDeviceMode);
pDevMode := GlobalLock(hDevicemode);
with pDevMode^ do
begin
dmFields := dmFields or DM_ORIENTATION;
dmOrientation := DMORIENT_LANDSCAPE;
end;
{Cannot use NewPage here since the ResetDc will only work between
EndPage and StartPage.
As a consequence the Printer.PageCount is not updated.}
Windows.EndPage(Printer.Handle);
if ResetDC(canvas.Handle, pDevMode^) = 0 then
ShowMessage('ResetDC failed, ' + SysErrorMessage(GetLastError));
GlobalUnlock(hDeviceMode);
Windows.StartPage(Printer.Handle);
Printer.Canvas.Refresh;
Canvas.font.size := 20;
Canvas.font.name := 'Arial';
Canvas.TextOut(50, 50, 'This is landscape');
finally
EndDoc;
end;
end;
end;
The orientation change requires a call to the API function ResetDC, and this function only succeeds if it is called after EndPage and before StartPage. Since the TPrinter.NewPage method does both you cannot use it. The above works but the internal page count of the Printer object is not updated, you have to maintain your own if you need to display it in the printed pages.
2009. április 7., kedd
How to determine which track the current CD is on
Problem/Question/Abstract:
How to determine which track the current CD is on
Answer:
Here's an easy way to do it: create a timer and put this code in the OnTimer event:
var
Trk, Min, Sec: Word;
begin
with MediaPlayer1 do
begin
Trk := MCI_TMSF_TRACK(Position);
Min := MCI_TMSF_MINUTE(Position);
Sec := MCI_TMSF_SECOND(Position);
Label1.Caption := Format('%.2d', [Trk]);
Label2.Caption := Format('%.2d:%.2d', [Min, Sec]);
end;
end;
Add MMSystem to the uses clause in Unit1. This will show current track and time.
2009. április 6., hétfő
Attaching captions to non visual objects
Problem/Question/Abstract:
Non visual components don't have caption properties of their own and all the components of one kind look alike. Identifying them at design time becomes increasingly difficult with each non visual component you add.
Answer:
You can identify a non visual component at design time by selecting the 'Show component captions' option in the Environment Options dialog. You can now see the name property of the component displayed under its icon.
2009. április 5., vasárnap
How to set the printer paper size
Problem/Question/Abstract:
I want to set the format of my page to a particular format for the printer that is not A4 (the default) but B5. How can I do this?
Answer:
You have to descend into the depth of the API for that and modify the printers DEVMODE record. Note that you should first try to select a paper type and let the driver figure out the bin for that. See win32.hlp entry for DEVMODE for a list of valid paper format ID's.
var
Device, Driver, Port: array[0..80] of Char;
DevMode: THandle;
pDevmode: PDeviceMode;
begin
{Get printer device name etc.}
Printer.GetPrinter(Device, Driver, Port, DevMode);
{force reload of DEVMODE}
Printer.SetPrinter(Device, Driver, Port, 0);
{get DEVMODE handle}
Printer.GetPrinter(Device, Driver, Port, DevMode);
if Devmode <> 0 then
begin
{lock it to get pointer to DEVMODE record}
pDevMode := GlobalLock(Devmode);
if pDevmode <> nil then
try
with pDevmode^ do
begin
{modify paper size}
dmPapersize := DMPAPER_B5;
{tell printer driver that dmPapersize field contains data it needs to inspect}
dmFields := dmFields or DM_PAPERSIZE;
end;
finally
{unlock DEVMODE handle}
GlobalUnlock(Devmode);
end;
end;
end;
You need to do this before a BeginDoc has been performed.
If this does not work for your purpose you have to modify the dmDefaultSource field of the DEVMODE (same principle as above). Windows.Pas defines a bunch of DMBIM_* constants but there is no guarantee that your printer will support them all (or even use the constant for the bin you think it should use). Better ask it for the bins it supports.
uses winspool;
procedure GetBinnames(sl: TStrings);
type
TBinName = array[0..23] of Char;
TBinNameArray = array[1..High(Integer) div Sizeof(TBinName)] of TBinName;
PBinnameArray = ^TBinNameArray;
TBinArray = array[1..High(Integer) div Sizeof(Word)] of Word;
PBinArray = ^TBinArray;
var
Device, Driver, Port: array[0..255] of Char;
hDevMode: THandle;
i, numBinNames, numBins, temp: Integer;
pBinNames: PBinnameArray;
pBins: PBinArray;
begin
Printer.PrinterIndex := -1;
Printer.GetPrinter(Device, Driver, Port, hDevmode);
numBinNames := WinSpool.DeviceCapabilities(Device, Port, DC_BINNAMES, nil, nil);
numBins := WinSpool.DeviceCapabilities(Device, Port, DC_BINS, nil, nil);
if numBins <> numBinNames then
begin
raise Exception.Create('DeviceCapabilities reports different number of bins and ' + 'bin names!');
end;
if numBinNames > 0 then
begin
pBins := nil;
GetMem(pBinNames, numBinNames * Sizeof(TBinname));
GetMem(pBins, numBins * Sizeof(Word));
try
WinSpool.DeviceCapabilities(Device, Port, DC_BINNAMES, Pchar(pBinNames), nil);
WinSpool.DeviceCapabilities(Device, Port, DC_BINS, Pchar(pBins), nil);
sl.clear;
for i := 1 to numBinNames do
begin
temp := pBins^[i];
sl.addObject(pBinNames^[i], TObject(temp));
end;
finally
FreeMem(pBinNames);
if pBins <> nil then
FreeMem(pBins);
end;
end;
end;
The integers in the DC_BINS array, which end up in the passed TStrings descendents Object property, are what you need to use for dmDefaultSource.
2009. április 4., szombat
Converting Integers to Base n
Problem/Question/Abstract:
How do I convert integers from Decimal to Base n and vice versa.
Answer:
Solve 1:
unit BaseFunctions;
{Unit for conversion functions Dec_To_Base and Base_To_Dec.}
{These functions are designed to convert integers from Decimal to Base n}
{They can be used to create serial numbers for Compaq, etc.}
{See below for usage.}
{Written by Dave Murray, Nov 2000.}
interface
uses
SysUtils;
function Dec_To_Base(nBase, nDec_Value, Lead_Zeros: integer; cOmit: string): string;
function Base_To_Dec(nBase: integer; cBase_Value, cOmit: string): integer;
implementation
function Dec_To_Base(nBase, nDec_Value, Lead_Zeros: integer; cOmit: string): string;
{Function : converts decimal integer to base n, max = Base36
Parameters : nBase = base number, ie. Hex is base 16
nDec_Value = decimal to be converted
Lead_Zeros = min number of digits if leading zeros required
cOmit = chars to omit from base (eg. I,O,U,etc)
Returns : number in base n as string}
var
Base_PChar: PChar;
Base_String: string;
To_Del, Modulus, DivNo: integer;
temp_string: string;
i, nLen, Len_Base: integer;
begin
{initialise..}
Base_String := '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; {max = Base36}
To_Del := 0;
Modulus := 0;
DivNo := nDec_Value;
result := '';
if (nBase > 36) then
nBase := 36; {max = Base36}
cOmit := UpperCase(cOmit);
{build string to fit specified base}
if not (cOmit = '') then
begin
{iterate thru' ommited letters}
nLen := Length(cOmit);
for i := 1 to nLen do
begin
To_Del := Pos(cOmit[i], Base_String); {find position of letter}
if (To_Del > 0) then
begin
{remove letter from base string}
Len_Base := Length(Base_String);
temp_string := Copy(Base_String, 0, To_Del - 1);
temp_string := temp_string + Copy(Base_String, To_Del + 1, Len_Base - To_Del);
Base_String := temp_string;
end; {if To_Del>0..}
end; {for i..}
end; {if not cOmit=''..}
{ensure string is required length for base}
SetLength(Base_String, nBase);
Base_PChar := PChar(Base_String);
{divide decimal by base & iterate until zero to convert it}
while DivNo > 0 do
begin
Modulus := DivNo mod nBase; {remainder is next digit}
result := Base_PChar[Modulus] + result;
DivNo := DivNo div nBase;
end; {while..}
{fix zero value}
if (Length(result) = 0) then
result := '0';
{add required leading zeros}
if (Length(result) < Lead_Zeros) then
for i := 1 to (Lead_Zeros - Length(result)) do
result := '0' + result;
end; {function Dec_To_Base}
function Base_To_Dec(nBase: integer; cBase_Value, cOmit: string): integer;
{Function : converts base n integer to decimal, max = Base36
Parameters : nBase = base number, ie. Hex is base 16
cBase_Value = base n integer (as string) to be converted
cOmit = chars to omit from base (eg. I,O,U,etc)
Returns : number in decimal as string}
var
Base_PChar: PChar;
Base_String: string;
To_Del, Unit_Counter: integer;
temp_string: string;
i, nLen, Len_Base: integer;
begin
{initialise..}
Base_String := '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; {max = Base36}
To_Del := 0;
Unit_Counter := nBase;
result := 0;
if (nBase > 36) then
nBase := 36; {max = Base36}
cOmit := UpperCase(cOmit);
cBase_Value := UpperCase(cBase_Value); {ensure uppercase letters}
{build string to fit specified base}
if not (cOmit = '') then
begin
{iterate thru' ommited letters}
nLen := Length(cOmit);
for i := 1 to nLen do
begin
To_Del := Pos(cOmit[i], Base_String); {find position of letter}
if (To_Del > 0) then
begin
{remove letter from base string}
Len_Base := Length(Base_String);
temp_string := Copy(Base_String, 0, To_Del - 1);
temp_string := temp_string + Copy(Base_String, To_Del + 1, Len_Base - To_Del);
Base_String := temp_string;
end; {if To_Del>0..}
end; {for i..}
end; {if not cOmit=''..}
{ensure string is required length for base}
SetLength(Base_String, nBase);
Base_PChar := PChar(Base_String);
{iterate thru digits of base n value, each digit is a multiple of base n}
nLen := Length(cBase_Value);
if (nLen = 0) then
result := 0 {fix zero value}
else
begin
for i := 1 to nLen do
begin
if (i = 1) then
unit_counter := 1 {1st digit = units}
else if (i > 1) then
unit_counter := unit_counter * nBase; {multiples of base}
result := result
+ ((Pos(Copy(cBase_Value, (Length(cBase_Value) + 1) - i, 1), Base_PChar) - 1)
* unit_counter);
end; {for i:=1..}
end; {else begin..}
end; {function Base_To_Dec}
end. {unit BaseFunctions}
Solve 2:
function Dec2Numb(N: Longint; A, B: Byte): string;
var
C: Integer;
{$IFDEF RX_D4}
Number: Cardinal;
{$ELSE}
Number: Longint;
{$ENDIF}
begin
if N = 0 then
Result := '0'
else
begin
{$IFDEF RX_D4}
Number := Cardinal(N);
{$ELSE}
Number := N;
{$ENDIF}
Result := '';
while Number > 0 do
begin
C := Number mod B;
if C > 9 then
C := C + 55
else
C := C + 48;
Result := Chr(C) + Result;
Number := Number div B;
end;
end;
if Result <> '' then
Result := AddChar('0', Result, A);
end;
function Numb2Dec(S: string; B: Byte): Longint;
var
I, P: Longint;
begin
I := Length(S);
Result := 0;
S := UpperCase(S);
P := 1;
while (I >= 1) do
begin
if S[I] > '@' then
Result := Result + (Ord(S[I]) - 55) * P
else
Result := Result + (Ord(S[I]) - 48) * P;
Dec(I);
P := P * B;
end;
end;
Code from RXLib library.
2009. április 3., péntek
Difference between SQL Server and MSSQL in BDE Adminstration SERVER TYPE
Problem/Question/Abstract:
Difference between SQL Server and MSSQL in BDE Adminstration SERVER TYPE, are both of them equal?
Answer:
Diffrence between MSSQL and SQL Server is narrow.
MSSQL take from Microsoft SQL and SQL Server from other vendors.
MSSQL drivers work without ODBC drivers but SQL Server need ODBC drivers and work with them.
In Application it is obvious brife that performance is higher if use MSSQL + BDE, instead of SQL SERVER + BDE + ODBC.
2009. április 2., csütörtök
Universal Naming Convention (UNC)
Problem/Question/Abstract:
For file-based applications, how is the Universal Naming Convention obtained for path names?
Answer:
To get the UNC name of a drive-based path, use the Windows API call WNetGetUniversalName. This function takes a drive-based path (i.e., fully qualified file name) and returns its UNC equivalent.
Be forewarned, though: This call is not supported by Windows 95. Here's something that should work if you're in NT:
function GetUNCName(PathStr: string): string;
var
bufSize: DWord;
buf: TUniversalNameInfo;
msg: string;
begin
bufSize := SizeOf(TUniversalNameInfo);
if (WNetGetUniversalName(PChar(PathStr), UNIVERSAL_NAME_INFO_LEVEL,
buf, bufSize) > 0) then
case GetLastError of
ERROR_BAD_DEVICE: msg := 'ERROR_BAD_DEVICE';
ERROR_CONNECTION_UNAVAIL: msg := 'ERROR_CONNECTION_UNAVAIL';
ERROR_EXTENDED_ERROR: msg := 'ERROR_EXTENDED_ERROR';
ERROR_MORE_DATA: msg := 'ERROR_MORE_DATA';
ERROR_NOT_SUPPORTED: msg := 'ERROR_NOT_SUPPORTED';
ERROR_NO_NET_OR_BAD_PATH: msg := 'ERROR_NO_NET_OR_BAD_PATH';
ERROR_NO_NETWORK: msg := 'ERROR_NO_NETWORK';
ERROR_NOT_CONNECTED: msg := 'ERROR_NOT_CONNECTED';
end
else
msg := buf.lpUniversalName;
Result := msg;
end;
2009. április 1., szerda
How to retrieve the last character in a TMemo
Problem/Question/Abstract:
How to retrieve the last character in a TMemo
Answer:
var
s: string;
c: char;
begin
with Memo1.Lines do
begin
{Get the last line}
s := Strings[Count - 1];
{Get the last character}
c := s[Length(s)];
end;
end;
Feliratkozás:
Bejegyzések (Atom)