各種編碼轉換,是編程的一個基本技能,此技能與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)
- 0.1 教程說明
- 0.2 delphi xe8 安裝
- 0.2.2 XE 10.3.3 安裝
- 0.3 delphi IDE 的非常必要的配置
- 0.4 調試中的異常處理
- 0.5 工程路徑設置
- 0.6 開發工具界面切換成中文的問題
- 一、實用技巧
- 0.嘗試為event取名叫伊文特
- 1.各種(變量)數據在內存中是什么樣子的?
- 2
- 3
- 4.亂碼問題
- 5
- 二、多線程
- 三、DLL相關
- 1.DLL中函數參數如何設計?
- 2.調用易語言DLL識別驗證碼
- 四、界面設計
- 1.關于解耦問題
- 2.登錄功能設計
- 五、面向對象基礎知識
- 1.窗口間傳遞值
- 3.避免又臭又長的裹腳布
- 2.擴展 TStringGrid , delphi 7 示例
- 六、初學者誤區集錦
- 七 TList 集合
- 1.附加信息Pointer設計
- 2.用 TList 來建立組件間的聯系
- 3.泛型 TList<T> 示例