Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
delphi是一种将十六进制字符串转换为二进制字符串的快速方法_Delphi - Fatal编程技术网

delphi是一种将十六进制字符串转换为二进制字符串的快速方法

delphi是一种将十六进制字符串转换为二进制字符串的快速方法,delphi,Delphi,我必须将十六进制字符串转换成这样的二进制字符串 "F" -> "‭1111‬" "A" -> "‭1010‬" "1AF1" -> "1101011110001" 我有这个功能: function HexToBin(Hexadecimal: string): string; const BCD: array [0..15] of string = ('0000', '0001', '0010', '0011', '0100', '0101', '0110', '0

我必须将十六进制字符串转换成这样的二进制字符串

"F" -> "‭1111‬"
"A" -> "‭1010‬"
"1AF1" -> "1101011110001"
我有这个功能:

function HexToBin(Hexadecimal: string): string;
const
  BCD: array [0..15] of string =
    ('0000', '0001', '0010', '0011', '0100', '0101', '0110', '0111',
    '1000', '1001', '1010', '1011', '1100', '1101', '1110', '1111');
var
  i: integer;
begin
  Result := '';
  for i := Length(Hexadecimal) downto 1 do
    Result := BCD[StrToInt('$' + Hexadecimal[i])] + Result;
end; 
我这样称呼它:

for I := 0 to Trunc(tcpFrame.Length/100) do
begin
   str := copy(tcpFrame , (I*100)+1 , 100  );
   data  := data +  HexToBin( str );
end;
但对于像50-60MB字符串这样的大数据来说,这真的很慢


有更好更快的方法吗?

我认为主要的问题是,您一次只向字符串添加一个部分

在Delphi中,通过一次添加一个小部分来构建动态数组或字符串非常缓慢。更好的方法是将数组/字符串预先分配到较大的大小,然后填充其内容。如果您知道开始时的最终长度,请使用此尺寸;否则,请分块分配

在这种情况下,我们知道最后的长度

此想法的示例实现:

function HexStrToBinStr(const AHexStr: string): string;
var
  i, j: Integer;
const
  HexParts: array[0..$F] of string =
    (
      {0} '0000',
      {1} '0001',
      {2} '0010',
      {3} '0011',
      {4} '0100',
      {5} '0101',
      {6} '0110',
      {7} '0111',
      {8} '1000',
      {9} '1001',
      {A} '1010',
      {B} '1011',
      {C} '1100',
      {D} '1101',
      {E} '1110',
      {F} '1111'
    );
begin
  SetLength(Result, 4 * AHexStr.Length);
  j := 1;
  for i := 1 to AHexStr.Length do
  begin
    case AHexStr[i] of
      '0'..'9':
        Move(HexParts[Ord(AHexStr[i]) - Ord('0')][1], Result[j], sizeof(char) * 4);
      'A'..'F':
        Move(HexParts[$A + Ord(AHexStr[i]) - Ord('A')][1], Result[j], sizeof(char) * 4);
      'a'..'f':
        Move(HexParts[$A + Ord(AHexStr[i]) - Ord('a')][1], Result[j], sizeof(char) * 4);
    else
      raise EConvertError.CreateFmt('Invalid hexadecimal string "%s".', [AHexStr]);
    end;
    Inc(j, 4);
  end;
end;
事实上,我不计算中间
'$'+Hexadecimal[I]
字符串和调用
strotint
也可能会加快速度


奖励练习:作为奖励练习,通过添加参数
APrettyPrint:Boolean=False
修改此代码,如果
True
,则在每组四位之间添加一个空格。当然,您仍然应该预先分配。

似乎与十六进制或二进制无关。当然,这只是关于串接字符串。预先分配字符串。你知道它有多长。然后使用十六进制到二进制的查找表填写字符。有没有理由将如此大量的二进制数据存储为十六进制文本?有时候,当你在进行优化时,退一步并在后面两步进行更改是很有用的,这样可以避免以后不得不处理一些麻烦的事情。如果您可以完全避免十六进制作为文本,那么这可能是首选的解决方案。@J。。。我从无线电发射机接收到一些捕获的图像数据(字节),然后将它们转换为十六进制字符串。我必须将它们转换为二进制字符串,并找到一个同步字来显示图像。现在图像正在显示,但处理速度较低,我正在尝试加速应用程序的每个部分。我不知道是否有可能在字节数组中找到一个40位的同步字,所以我使用了上面的解决方案@佩曼夫。我从来没有听说过一台收音机能传送编码为十六进制文本的大二进制图像。为什么会这样?是你让它这么做的,还是这是别人的坏主意?我仍然很好奇这个设计决定来自何处以及为什么。@peimanF。嗯,是的,您应该能够直接进行所有这些比较-转换为二进制字符串进行比较非常缓慢,而且完全没有必要。这将是值得张贴一个后续问题,解释您的实际问题,详细显示您正在接收的数据格式和您正在寻找什么。会有更好的方法来做你想做的事。