【问题标题】:128 bit operation with delphidelphi 128位运算
【发布时间】:2011-09-10 18:05:31
【问题描述】:

我需要将十六进制值转换为十进制整数。有没有单位可以做到这一点?

在网上我找到了一些关于它的东西,但它对我没有多大帮助。我知道使用inline asm 可以将其表示为四个32 位Integer 的打包数组。我发现将 int32 或 int64 转换为 int128,反之亦然,但没有发现任何例如两个 int64 和执行 int128 的问题,我也发现在 asm 内联中搜索 emule div 运算符的问题,mul运算符和sum 运算符。

所以我问是否有人可以帮助我解决这个问题。我的目标是取一个十六进制字符串并将其转换为十进制,然后计算base 35(0..9,A..Z)中的等效值。 非常感谢。

【问题讨论】:

  • 什么数据结构保存你的 128 位整数?
  • 99% 确定他指的是 Base36。
  • (a) 关于数据结构,我发现:类型 Int128 = Int32 的打包数组 [0..3]。 (b) 对于基数 35,我的意思是从 0 到 9 的数字和从 A 到 Z 的字母。例如,我们有从 0 到 9 的数字和从 A 到 F 的字母。一般来说,我的意思是数字 x mod 35,其余从 0到 34,其中 34 例如代表 Z。(c)不,不是 base36,我的意思是 base35,但 base36 也没有太大变化;在我的情况下需要在 base35 工作。
  • 也许可以试试支持任意大小整数数学的库,例如link
  • 0..9,a..z 为 36 位

标签: delphi math delphi-xe2


【解决方案1】:

如果您将十六进制字符串转换为字节数组(参见 SysUtils),您可以使用以下代码将其转换为基数 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;

然后将base 35字节转换成字符:

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;

我认为你不需要 128 位数学......

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 2020-07-06
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 2017-09-03
    相关资源
    最近更新 更多