ฉันมีตัวแปร TBytes ที่มีค่า [0,0,15,15] ฉันจะแปลงเป็น "00FF" ได้อย่างไร?
ฉันไม่ต้องการใช้ลูป เพราะตรรกะนี้จะถูกใช้ในฟังก์ชันที่เน้นเวลา
(ฉันลองใช้ BinToHex แต่ฉันไม่สามารถทำงานกับตัวแปรสตริงได้)
ขอขอบคุณและขอแสดงความนับถือ,
ปาวัน.
ฉันมีตัวแปร TBytes ที่มีค่า [0,0,15,15] ฉันจะแปลงเป็น "00FF" ได้อย่างไร?
ฉันไม่ต้องการใช้ลูป เพราะตรรกะนี้จะถูกใช้ในฟังก์ชันที่เน้นเวลา
(ฉันลองใช้ BinToHex แต่ฉันไม่สามารถทำงานกับตัวแปรสตริงได้)
ขอขอบคุณและขอแสดงความนับถือ,
ปาวัน.
// Swapping is necessary because x86 is little-endian.
function Swap32(value: Integer): Integer;
asm
bswap eax
end;
function FourBytesToHex(const bytes: TBytes): string;
var
IntBytes: PInteger;
FullResult: string;
begin
Assert(Length(bytes) = SizeOf(IntBytes^));
IntBytes := PInteger(bytes);
FullResult := IntToHex(Swap32(IntBytes^), 8);
Result := FullResult[2] + FullResult[4] + FullResult[6] + FullResult[8];
end;
หากบรรทัดสุดท้ายดูแปลกๆ เล็กน้อย อาจเป็นเพราะคุณร้องขอให้เปลี่ยนอาร์เรย์สี่ไบต์เป็นสตริงสี่อักขระ ในขณะที่ในกรณีทั่วไป ต้องใช้เลขฐานสิบหก แปด หลักเพื่อแสดงอักขระสี่ตัว ค่าไบต์ ฉันแค่สันนิษฐานว่าค่าไบต์ของคุณทั้งหมดต่ำกว่า 16 ดังนั้นจึงต้องใช้เลขฐานสิบหกเพียงหลักเดียวเท่านั้น หากตัวอย่างของคุณพิมพ์ผิด เพียงแทนที่สองบรรทัดสุดท้ายด้วยบรรทัดนี้:
Result := IntToHex(Swap32(IntBytes^), 8);
อย่างไรก็ตาม คุณจะไม่สามารถปฏิบัติตามข้อกำหนดในการห้ามลูปได้ IntToHex
ใช้การวนซ้ำภายใน
อันนี้ค่อนข้างเร็วและใช้ได้กับอาเรย์ทุกขนาด .. มันเหมือนกับ BinToHex แต่แทนที่จะคาดหวังค่า 0..255 ไบต์กลับใช้แค่แทะต่ำเท่านั้น
procedure BinToSingleHex(Buffer, Text: PAnsiChar; BufSize: Integer);
const
Convert: array[0..15] of AnsiChar = '0123456789ABCDEF';
var
I: Integer;
begin
for I := 0 to BufSize - 1 do
begin
Text[0] := Convert[Byte(Buffer[I]) and $F];
Inc(Text);
end;
end;
แอสเซมเบลอร์ที่ทำเช่นเดียวกัน:
procedure BinToSingleHex(Buffer, Text: PAnsiChar; BufSize: Integer);assembler;
asm
PUSH ESI
PUSH EDI
MOV ESI,EAX
MOV EDI,EDX
MOV EDX,0
JMP @@1
@@0: DB '0123456789ABCDEF'
@@1: LODSB
AND DL,AL
AND DL,0FH
MOV AL,@@0.Byte[EDX]
STOSB
DEC ECX
JNE @@1
POP EDI
POP ESI
end;
การใช้งาน:
type THexDigit=0..15;
const ArSize=16;
var Ar:array[0..Pred(ArSize)] of THexDigit=(0,1,2,3,4,5,6,7,8,9,8,7,6,5,4,3);
S:Array[0..Pred(ArSize)] of AnsiChar;
BinToSingleHex(@Ar,S,Length(Ar));
WriteLn(S);
ไปงานปาร์ตี้สายไปสักหน่อย แต่ทำไมไม่ลองตารางค้นหาแบบธรรมดาดูล่ะ
const
HexChars : Array[0..15] of Char = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
สมมติว่าค่า TBytes เท่ากับ 0..15
Function (ABytea: TBytes): string
begin
Result := HexChars[ABytea[0]];
Result := Result + HexChars[ABytea[1]];
Result := Result + HexChars[ABytea[2]];
Result := Result + HexChars[ABytea[3]];
end;
แน่นอนว่าเรียบร้อยกว่าด้วยการวนซ้ำ :) และจำเป็นต้องแก้ไขค่าไบต์ที่สูงกว่า 15:
begin
Result := HexChars[ABytea[0] shr 4];
Result := Result + HexChars[ABytea[0] and $0F];
Result := Result + HexChars[ABytea[1] shr 4];
Result := Result + HexChars[ABytea[1] and $0F];
Result := Result + HexChars[ABytea[2] shr 4];
Result := Result + HexChars[ABytea[2] and $0F];
Result := Result + HexChars[ABytea[3] shr 4];
Result := Result + HexChars[ABytea[3] and $0F];
end;
ยังคงเรียบร้อยกว่าด้วยการวนซ้ำโดยเฉพาะอย่างยิ่งหาก TBytes มีขนาดใหญ่ขึ้น