【问题标题】:Converting Strings to Hex in a performant way以高效的方式将字符串转换为十六进制
【发布时间】:2015-03-05 14:51:33
【问题描述】:

我开发了以下函数来将字符串转换为十六进制值。

function StrToHex(const S: String): String;
const
  HexDigits: array[0..15] of Char = '0123456789ABCDEF';
var
  I: Integer;
  P1: PChar;
  P2: PChar;
  B: Byte;
begin

  SetLength(Result, Length(S) * 2);
  P1 := @S[1];
  P2 := @Result[1];

  for I := 1 to Length(S) do
  begin
    B := Byte(P1^);
    P2^ := HexDigits[B shr 4];
    Inc(P2);
    P2^ := HexDigits[B and $F];
    Inc(P1);
    Inc(P2);
  end; 

end; 

现在我想知道是否有更有效的方法来转换字符串?

【问题讨论】:

    标签: delphi


    【解决方案1】:

    取决于您的 Delphi 版本:

    D5-D2007

    uses classes;
    function String2Hex(const Buffer: Ansistring): string;
    begin
      SetLength(result, 2*Length(Buffer));
      BinToHex(@Buffer[1], @result[1], Length(Buffer));
    end;
    

    D2009+

    uses classes;
    function String2Hex(const Buffer: Ansistring): string;
    begin
      SetLength(result, 2*Length(Buffer));
      BinToHex(@Buffer[1], PWideChar(@result[1]), Length(Buffer));
    end;
    

    【讨论】:

      【解决方案2】:

      试试这个

         function String2Hex(const Buffer: Ansistring): string;
         var
           n: Integer;
         begin
           Result := '';
           for n := 1 to Length(Buffer) do
             Result := LowerCase(Result + IntToHex(Ord(Buffer[n]), 2));
         end;
      

      【讨论】:

      • 太棒了!我刚刚做了一个性能测试,你的功能比我的更快(只是一点点)。谢谢!
      • 在确定它确实有效之前,您需要多久将字符串小写一次?
      • @Forlan07,再做一次测试。此示例中的代码为“缓冲区”中的每个字符重新分配一次 Result,使用 IntToHex 将数字转换为十六进制......它不可能更快!您的代码只分配一次内存,然后对文本执行一个 for 循环以将其全部转换为十六进制。
      • @Cosmin Prund:你是对的......似乎我花时间的一个函数中有一个错误。我只是用了一个不同的功能来花时间。
      【解决方案3】:

      我知道这是一个非常古老的话题,但我觉得我需要分享我关于这个问题的代码。多年来,我使用自己的 HexEncode,与 Forlan 的代码非常相似,但就在今天,我发现了一种更快的 Hex 编码方法。使用我的旧 HexEncode,编码一个 180kb 的二进制文件大约需要 50 秒,而使用这个函数需要 6 秒。

      function getHexEncode(txt : AnsiString) : AnsiString;
      var
        a : integer ;
        st : TStringStream;
        buf : array [0..1] of AnsiChar;
        tmp : ShortString;
      begin
        st := TStringStream.Create;
        st.Size := Length(txt)*2;
        st.Position := 0;
        for a:=1 to Length(txt) do
        begin
          tmp := IntToHex(Ord(txt[a]),2);
          buf[0] := tmp[1];
          buf[1] := tmp[2];
          st.Write(buf,2);
        end;
        st.Position := 0;
        Result := st.DataString;
        st.Free;
        //Result := '';  //my old code
        //for a:=1 to Length(txt) do Result := Result+IntToHex(Ord(txt[a]),2);  //my old code
      end;
      

      【讨论】:

        【解决方案4】:

        看起来已经足够好了,你总是可以有一个 byte->2 hex 数字查找表,但是在大多数情况下,这(和类似的优化)对我来说似乎有点过头了。

        【讨论】:

          【解决方案5】:

          // StrToInt('$' + MyString); 哎呀,没好好读题……

          【讨论】:

            猜你喜欢
            • 2018-01-31
            • 2018-01-22
            • 1970-01-01
            • 2013-02-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-11-07
            相关资源
            最近更新 更多