ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
各种编码转换,是编程的一个基本技能,此技能与DELPHI无关,它是编程基础技能。 要研究编码转换,封包解包数据,我们得有一个工具,查看数据在内存中的样子。 ~~~ // 研究字符的编码 // 要研究各种编码,最直接的办法就是在内存中去查看 // 将 B:=$AE 转换为 S:='AE'; 相当于 S:=IntToHex(B,2); // 从 Addr 地址取 AByteCount 个 Byte ,将其转为 HexStr function GenHexStr(Addr: Pointer; AByteCount: Integer): string; const Buff: array[0..15] of Char = ( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); // 查表,空间换时间,很常见且实用 var i: Integer; S: PByte; // 源-指针 D: PChar; // 目的地-指针 Hi, Lo: Byte; begin SetLength(result, AByteCount * 2); // 预设 Result 的长度与指针配合,可以避免 s:=s+'xx';这种低效率写法 S := Addr; D := PChar(result); for i := 0 to AByteCount - 1 do begin Hi := (S^ and $F0) shr 4; // 高位 D^ := Buff[Hi]; inc(D); Lo := (S^ and $0F); // 低位 D^ := Buff[Lo]; inc(D); inc(S); end; end; ~~~ 有了这个函数,我们就可以查看内存中的数据了。此外,还得有一个逆函数,将HexStr转为会(变量)数据。 ~~~ // 这两个函数,同时演示了指针的用法。 // 将 S:='AE'; 转换为 B:=$AE; 相当于 B:= StrToInt('$AE'); // 要确保 Dest 有足够的空间 procedure HexStrToBytes(AHexStr: string; Dest: Pointer); var i: Integer; S: PChar; // 源指针 D: PByte; // 目的地指针 Hi, Lo: Char; begin S := PChar(AHexStr); D := Dest; for i := 0 to (Length(AHexStr) div 2) - 1 do begin Hi := S^; if Hi in ['0'..'9'] then Dec(Hi, 48) // '0' 的 asc 码是48 else if Hi in ['A'..'Z'] then Dec(Hi, 55) // 'A' 的 asc 码是 65 , $A=10 所以减 55 else if Hi in ['a'..'z'] then Dec(Hi, 87) // 'a' 的 asc 码是 97 else raise Exception.Create('字串中有非Hex数字的字符:[' + Hi + ']'); // 异常是一种简洁的处理错误的手段。 // 如若不然的话,此处如何处理非 Hex 的字符呢?处理不了的问题,直接就引发异常。 inc(S); Lo := S^; if Lo in ['0'..'9'] then Dec(Lo, 48) // '0' 的 asc 码是48 else if Lo in ['A'..'Z'] then Dec(Lo, 55) // 'A' 的 asc 码是 65 , $A=10 所以减 55 else if Lo in ['a'..'z'] then Dec(Lo, 87) // 'a' 的 asc 码是 97 else raise Exception.Create('字串中有非Hex数字的字符:[' + Lo + ']'); D^ := (Ord(Hi) shl 4) + Ord(Lo); inc(S); inc(D); end; end; ~~~ 用法,以查看Integer在内存中的状态为例: ~~~ procedure TForm1.Button3Click(Sender: TObject); var n: Integer; sOut: string; begin n := $12AB34CD; sOut := GenHexStr(@n, 4); Memo1.Lines.Add('Hex Str:' + sOut); // sOut='CD34AB12' ,明显有高低位换位 end; ~~~ 本例由DELPHI 7 编写,程序中还有更多的数据类型在内存中的状态示例,如:ansiString, UnicodeString, Utf8String 您可以用此源码,研究一切数据在内存中的状态,永不被数据编码困扰。 [点击下载源码](https://www.jianguoyun.com/p/DZTz4BwQxMf4BRiR4Ds)