转载

缓存和字符串相互转换

使用方法:将缓存中数据转换成字符串并且进行了加密,然后将加密后的字符串通过SOCKET通信传输,接收方收到后,将字符串解密并且还原出数据。

可单独用于结构体的序列也可用于结构体序列+有规则字符串的序列,看似简单,其实万能而通用,有许多游戏都是这么传数据的,无非是改一改加密和解密的算法罢了。

unit EDcode;

//编码/解码函数库

{$WARNINGS OFF}

interface

usesWindows, SysUtils, Classes;

const

BUFFERSIZE=32768;

DEFBLOCKSIZE=24;

HEADCHAR = '#';TAILCHAR = '!';

const

CM_TEST = 1000;

CM_TEST2 = 1001;

const

SM_TEST = 9000;

SM_TEST2 = 9001;

type

TDefaultMessage=packed record  //Size=18

MsgID: word;

Param1: Integer;

Param2: integer;

Param3: integer;

Param4: Integer;

end;

function EncodeMessage (smsg: TDefaultMessage): AnsiString;

function DecodeMessage (str: AnsiString): TDefaultMessage;

function EncodeString (str: AnsiString): AnsiString;

function DecodeString (str: AnsiString): AnsiString;

function EncodeBuffer (buf: PAnsiChar; bufsize: integer): AnsiString;

procedure DecodeBuffer (src: AnsiString; buf: PAnsiChar; bufsize: integer);

function  MakeDefaultMsg (msgid:word; param1,param2,param3,param4:integer):TDefaultMessage;

var

CSEncode: TRTLCriticalSection;

implementation

varEncBuf, TempBuf: PAnsiChar;

function  MakeDefaultMsg (msgid:word; param1,param2,param3,param4:integer):TDefaultMessage;

begin

result.MsgID := msgid;

result.Param1 := param1;

result.Param2 := param2;

result.Param3 := param3;

result.Param4 := param4;

end;

procedure Encode6BitBuf (src, dest: PAnsiChar; srclen, destlen: integer);

var

i, restcount, destpos: integer;

made, ch, rest: byte;

begin

try

restcount := 0;

rest    := 0;

destpos  := 0;

for i:=0 to srclen - 1 do begin

if destpos >= destlen then break;

ch := byte (src[i]);

made := byte ((rest or (ch shr (2+restcount))) and $3F);

rest := byte (((ch shl (8 - (2+restcount))) shr 2) and $3F);

Inc (restcount, 2);

if restcount < 6 then begin

dest[destpos] := AnsiChar(made + $3C);

Inc (destpos);

end else begin

if destpos < destlen-1 then begin

dest[destpos]   := AnsiChar(made + $3C);

dest[destpos+1] := AnsiChar(rest + $3C);

Inc (destpos, 2);

end else begin

dest[destpos]   := AnsiChar(made + $3C);

Inc (destpos);

end;

restcount := 0;

rest := 0;

end;

end;

if restcount > 0 then begin

dest[destpos] := AnsiChar (rest + $3C);

Inc (destpos);

end;

dest[destpos] := #0;

except

end;

end;

procedure Decode6BitBuf (source: AnsiString; buf: PAnsiChar; buflen: integer);

const

Masks: array[2..6] of byte = ($FC, $F8, $F0, $E0, $C0);

var

i, len, bitpos, madebit, bufpos: integer;

ch, tmp, _byte: Byte;

begin

try

len := Length (source);

bitpos  := 2;

madebit := 0;

bufpos  := 0;

tmp   := 0;

for i:=1 to len do begin

if Integer(source[i]) - $3C >= 0 then

ch := Byte(source[i]) - $3C

else begin

bufpos := 0;

break;

end;

if bufpos >= buflen then break;

if (madebit+6) >= 8 then begin

_byte := Byte(tmp or ((ch and $3F) shr (6-bitpos)));

buf[bufpos] := AnsiChar(_byte);

Inc (bufpos);

madebit := 0;

if bitpos < 6 then Inc (bitpos, 2)

else begin

bitpos := 2;

continue;

end;

end;

tmp := Byte (Byte(ch shl bitpos) and Masks[bitpos]);

Inc (madebit, 8-bitpos);

end;

buf [bufpos] := #0;

except

end;

end;

function DecodeMessage (str: AnsiString): TDefaultMessage;

var

msg: TDefaultMessage;

begin

try

EnterCriticalSection (CSencode);

Decode6BitBuf (str, EncBuf, 1024);

Move (EncBuf^, msg, sizeof(TDefaultMessage));

Result := msg;

finally

LeaveCriticalSection (CSencode);

end;

end;

function DecodeString (str: AnsiString): AnsiString;

begin

try

EnterCriticalSection (CSencode);

Decode6BitBuf (str, EncBuf, BUFFERSIZE);

Result := StrPas (EncBuf);

finally

LeaveCriticalSection (CSencode);

end;

end;

procedure DecodeBuffer (src: AnsiString; buf: PAnsiChar; bufsize: integer);

begin

try

EnterCriticalSection (CSencode);

Decode6BitBuf (src, EncBuf, BUFFERSIZE);

Move (EncBuf^, buf^, bufsize);

finally

LeaveCriticalSection (CSencode);

end;

end;

function  EncodeMessage (smsg: TDefaultMessage): AnsiString;

begin

try

EnterCriticalSection (CSencode);

Move (smsg, TempBuf^, sizeof(TDefaultMessage));

Encode6BitBuf (TempBuf, EncBuf, sizeof(TDefaultMessage), 1024);

Result := StrPas (EncBuf); 

finally

LeaveCriticalSection (CSencode);

end;

end;

function EncodeString (str: AnsiString): AnsiString;

begin

try

EnterCriticalSection (CSencode);

Encode6BitBuf (PAnsiChar(str), EncBuf, Length(str), BUFFERSIZE);

Result := StrPas (EncBuf);

finally

LeaveCriticalSection (CSencode);

end;

end;

function  EncodeBuffer (buf: PAnsiChar; bufsize: integer): AnsiString;

begin

try

EnterCriticalSection (CSencode);

if bufsize < BUFFERSIZE then begin

Move (buf^, TempBuf^, bufsize);

Encode6BitBuf (TempBuf, EncBuf, bufsize, BUFFERSIZE);

Result := StrPas (EncBuf);

end else

Result := '';

finally

LeaveCriticalSection (CSencode);

end;

end;

initialization

begin

GetMem (EncBuf, BUFFERSIZE + 100);

GetMem (TempBuf, 2048);

InitializeCriticalSection(CSEncode);

end;

finalization

begin

FreeMem (EncBuf, BUFFERSIZE + 100);

FreeMem (TempBuf, 2048);

DeleteCriticalSection(CSEncode);

end;

end.

正文到此结束
Loading...