128 bit operation with delphi
I need to convert a hexadecimal value to a decimal integer. Is there some unit that can do this?
On the web I have found something about it but it is not helping me much. I understoo开发者_JAVA百科d that using inline asm
it is possible to represent it as a packed array of four 32 bit Integer
. I have found as convert a int32 or int64 to int128 and viceversa, but not found nothing for take for example two int64 and to do a int128 and too i have found issue searching in asm inline something that emule div
operator, mul
operator and sum
operator.
So I ask if someone can help me to solve this problem. My objective is to take a string in hexadecimal and convert it in decimal and after that calculate the equivalent value in base 35
(0..9, A..Z).
Thanks very much.
If you convert the hexadecimal string into an array of bytes (see SysUtils for that) you can use the follewing code to convert it into base 35:
function EncodeBaseX( const Values: array of Byte; var Dest: array of Byte; Radix: Integer ): Boolean;
var
i,j,Carry: Integer;
begin
// We're unsuccesful up to now
Result := False;
// Check if we have an output buffer and clear it
if Length( Dest ) = 0 then Exit;
System.FillChar( Dest[ 0 ], Length( Dest ), 0 );
// fill in the details
for i := 0 to High( Values ) do begin
Carry := Values[ i ];
for j := 0 to High( Dest ) do begin
Inc( Carry, Radix * Dest[ j ] );
Dest[ j ] := Carry and $ff;
Carry := Carry shr 8;
end;
if Carry <> 0 then Exit; // overflow
end;
// We're succesful
Result := True;
end;
{Bytes: array of byte (0..255); Dest: array of Byte(0..Radix-1)}
function DecodeBaseX( const Bytes: array of Byte; var Dest: array of Byte; Radix: Integer ): Boolean;
var
i,j,Carry: Integer;
B: array of Byte;
begin
// We're unsuccesful up to now
Result := False;
// Copy data
if Length( Bytes ) = 0 then Exit;
SetLength( B, Length( Bytes ) );
System.Move( Bytes[ 0 ], B[ 0 ], Length( B ) );
// fill in the details
for i := High( Dest ) downto 0 do begin
Carry := 0;
for j := High( Bytes ) downto 0 do begin
Carry := Carry shl 8 + B[ j ];
B[ j ] := Carry div Radix; Carry := Carry mod Radix;
end;
Dest[ i ] := Carry;
end;
// Check if we collected all the bits
Carry := 0;
for i := 0 to High( B ) do Carry := Carry or B[ i ];
// We're succesful if no bits stayed pending.
Result := ( Carry = 0 );
end;
Then transform the base 35 bytes into characters:
function EncodeKeyToString( const Num128Bits: array of Byte ): Ansistring;
var
Src: array [0..15] of Byte; // your 128 bits
Dest: array [0..24] of Byte;
i: Integer;
const
EncodeTable: AnsiString = '0123456789ABCDEFGHIJKLMNPQRSTUVWXYZ';
// O is not present to make base 35. If you want a different code, be my guest.
begin
// Convert to an array of 25 values between 0-35
System.Move( Num128Bits[ 0 ], Src[ 0 ], Length( Src ) ); // Copy data in our private placeholder
DecodeBaseX( Src, Dest, 35 );
// Convert to a representable string
SetLength( Result, Length( Dest ) );
for i := 0 to High( Dest ) do begin
Assert( Dest[ i ] < Length( EncodeTable ) );
Result[ i + 1 ] := EncodeTable[ 1 + Dest[ i ] ];
end;
end;
I don't think you need 128 bit math..
Good luck!
精彩评论