缓存和字符串相互转换

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

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

unit EDcode;
//编码/解码函数库
{$WARNINGS OFF}
interface

uses
   Windows, 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

var
   EncBuf, 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.

时间: 2024-10-23 21:35:03

缓存和字符串相互转换的相关文章

JAVA的整型与字符串相互转换

JAVA的整型与字符串相互转换 1如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或 i = Integer.parseInt([String],[int radix]); 2). int i = Integer.valueOf(my_str).intValue(); 注: 字串转成 Double, Float, Long 的方法大同小异. 2 如何将整数 int 转换成字串 String ? A

(转)JAVA的整型与字符串相互转换

JAVA的整型与字符串相互转换1如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Integer.parseInt([String]); 或         i = Integer.parseInt([String],[int radix]); 2). int i = Integer.valueOf(my_str).intValue(); 注: 字串转成 Double, Float, Long 的方法大同小异. 2 如何将整数 int 转换成字串 Str

字典和JSON格式字符串相互转换

在iOS开发中,和服务器交互中,经常用到字典和JSON格式字符串相互转换. 1.JSON格式字符串转字典 + (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString { if (jsonString == nil) { return nil; } NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; NSError *err; NSDi

整型和字符串相互转换

我们写程序的时候经常会遇到整型和字符串相互转换的问题,这里要用到几个函数,itoa(),atoi(),sprintf()下面来介绍下这几个函数的具体用法! itoa 功 能:把一整数转换为字符串 用 法:char *itoa(int value, char *string, int radix); 详细解释:itoa是英文integer to array(将int整型数转化为一个字符串,并将值保存在数组string中)的缩写. 参数: value: 待转化的整数. radix: 是基数的意思,即

python 日期、时间、字符串相互转换

python 日期.时间.字符串相互转换 在python中,日期类型date和日期时间类型dateTime是不能比较的. (1)如果要比较,可以将dateTime转换为date,date不能直接转换为dateTime import datetime dateTime_p = datetime.datetime.now() date_p = dateTime_p.date() print(dateTime_p) #2019-01-30 15:17:46.573139 print(date_p) #

js中 json对象与json字符串相互转换的几种方式

以下总结js中 json对象与json字符串相互转换的几种方式: 一.JSON对象转化为JSON字符串 1.使用JSON.stringify()方法进行转换 该方法不支持较老版本的IE浏览器,比如:ie8(兼容模式).ie7.ie6. var jsonStr = JSON.stringify(jsonObj); alert(jsonStr); var jsonStr = jsonObj.toJSONString(); alert(jsonStr); 二.JSON字符串转化为JSON对象 1.使用

java中获取当前系统时间,并与字符串相互转换格式,或者转化成秒数,天数等整数

转换成秒数 Date类有一个getTime()可以换回秒数,例如: public class DateToSecond { public static void main(String[] args) { Date date = new Date(System.currentTimeMillis()); System.out.println(date.getTime()); } } 与字符串格式相互转换 一. 获取当前系统时间和日期并格式化输出: import java.util.Date; i

【转】Date类学习总结(Calendar Date 字符串 相互转换 格式化)

原文网址:http://www.blogjava.net/jerry-zhaoj/archive/2008/10/08/233228.html Date类学习总结 1.计算某一月份的最大天数 Calendar time=Calendar.getInstance();time.clear();time.set(Calendar.YEAR,year); //year 为 int time.set(Calendar.MONTH,i-1);//注意,Calendar对象默认一月为0           

使用jackson对Java对象与JSON字符串相互转换的一些总结

本文为菠萝大象原创,如要转载请注明出处.http://www.blogjava.net/bolo 代码无真相,为了最简单的说明,我直接上代码. public class User { private String name; private Gender gender; private List<Account> accounts; 省略get和set方法 ... } public enum Gender { MALE, FEMALE } public class Account { priv