how to convert byte array to its hex representation in Delphi

天涯浪子 提交于 2019-12-24 06:06:45

问题


I have TBytes variable with a value [0,0,15,15]. How can I convert it to "00FF" ?

I dont want to use loops, bcoz this logic to be used in time intensive function.

(I tried using BinToHex, but I could not get it working with string variable.)

Thanks & Regards,

Pavan.


回答1:


// 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;

If that last line looks a little strange, it's because you requested a four-byte array be turned into a four-character string, whereas in the general case, eight hexadecimal digits are required to represent a four-byte value. I'm simply assumed that your byte values are all below 16, so only one hexadecimal digit is needed. If your example was a typo, then simply replace the last two lines with this one:

Result := IntToHex(Swap32(IntBytes^), 8);

By the way, your requirement forbidding loops will not be met. IntToHex uses a loop internally.




回答2:


function ByteToHex(InByte:byte):shortstring;
const Digits:array[0..15] of char='0123456789ABCDEF';
begin
 result:=digits[InByte shr 4]+digits[InByte and $0F];
end;

Example :
MyHex := ByteTohex($FF);
the result
MyHex is "FF".

MyHex := ByteTohex(255);
the result
MyHex is "FF".

MyHex := ByteTohex($55);
the result
MyHex is "55".



回答3:


This one is quite fast and works with any array size.. It's like BinToHex, but instead of expecting 0..255 byte values, it only uses the low nibble.

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;

Assembler that does the same:

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;

usage:

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);



回答4:


Bit late to the party but why not a simple lookup table?

const
HexChars : Array[0..15] of Char = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');

Assuming TBytes values of 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;

of course neater with a loop :) and needs modifying for byte values above 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;

Still neater with a loop especially if TBytes gets larger



来源:https://stackoverflow.com/questions/1060321/how-to-convert-byte-array-to-its-hex-representation-in-delphi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!