вот так у меня все заработало:
Код:
unit Opcode;
interface
var
_1_byte_table: string;
_2_byte_table: string;
_seed: integer;
procedure _init_tables();
function _encode_1ID(_ID: char):char;
function _encode_2ID(_ID: char):char;
implementation
function _pseudo_rand: integer;
var
a : integer;
begin
a := (Int64(_seed) * $343fd + $269EC3) and $FFFFFFFF;
_seed := a;
result := (_seed shr $10) and $7FFF;
end;
procedure _init_tables();
var
i : integer;
x : Char;
x2: Word;
rand_pos : integer;
cur_pos : integer;
begin
_1_byte_table := '';
_2_byte_table := '';
for i := 0 to $D0 do begin
_1_byte_table := _1_byte_table + chr(i);
end;
for i := 0 to $66 do begin
_2_byte_table := _2_byte_table + chr(i) + #$0;
end;
for i := 2 to $D1 do begin
rand_pos := (_pseudo_rand mod i) + 1;
x := _1_byte_table[rand_pos];
_1_byte_table[rand_pos] := _1_byte_table[i];
_1_byte_table[i] := x;
end;
cur_pos := 3;
for i := 2 to $67 do begin
rand_pos := _pseudo_rand mod i;
x2 := PWord(@_2_byte_table[rand_pos * 2 + 1])^;
PWord(@_2_byte_table[rand_pos * 2 + 1])^:=PWord(@_2_byte_table[cur_pos])^;
PWord(@_2_byte_table[cur_pos])^:=x2;
cur_pos := cur_pos + 2;
end;
cur_pos := Pos(#$12, _1_byte_table);
x := _1_byte_table[$13];
_1_byte_table[$13] := #$12;
_1_byte_table[cur_pos]:=x;
cur_pos := Pos(#$B1, _1_byte_table);
x := _1_byte_table[$B2];
_1_byte_table[$B2] := #$B1;
_1_byte_table[cur_pos]:=x;
end;
function _encode_1ID(_ID: char):char;
var
p: integer;
begin
p := pos(_ID, _1_byte_table);
_ID:=Char(p-1);
result:= _ID;
end;
function _encode_2ID(_ID: char):char;
var
p: integer;
begin
p:= pos(_ID, _2_byte_table);
_ID:=Char(((p + 1) shr 1) - 1);
result:= _ID;
end;
end.
приходит пакет KeyInit - берем последние 4 байта, копируем в _seed, вызываем _init_tables();
приходит пакет CharSelected, повторяем действия - берем последние 4 байта, копируем в _seed, вызываем _init_tables();
для кодирования ID пакетов - одноайдишные - _encode_1ID,
двух айдишные - для первого ID - _encode_1ID, для второго _encode_2ID.
работает на птске.