跳过源无法按预期工作

Skip'ing on a Source does not work as expected

本文关键字:工作      更新时间:2023-10-16

我使用Crypto++ 5.6.3,我需要FileSource Skip(...)函数。不幸的是,这个函数什么也不做!

下面是这个函数的一个例子:

string filename = ...;
string str;
FileSource file(filename, false, new HexEncoder(new StringSink(str)));
file.Skip(24);
file.PumpAll();

有人能帮我吗?

我使用Crypto++ 5.6.3并且我需要FileSource "skip(…)函数。不幸的是,这个函数什么也不做!

我可以在OS X 10.8.5和Ubuntu 14.04的Master, 5.6.3和5.6.2下使用字符串复制这个。

$ cat test.cxx
#include <string>
#include <iostream>
using namespace std;
#include <filters.h>
#include <hex.h>
using namespace CryptoPP;
int main(int argc, char* argv[])
{
  string str1, str2;
  HexEncoder enc(new StringSink(str1));
  for(unsigned int i=0; i < 32; i++)
    enc.Put((byte)i);
  enc.MessageEnd();
  cout << "str1: " << str1 <<endl;
  StringSource ss(str1, false, new StringSink(str2));
  ss.Skip(10);
  ss.PumpAll();
  cout << "str2: " << str2 << endl;
  return 0;
}

:

$ ./test.exe
str1: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
str2: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F

Crypto++ 5.6.2意义重大,因为它是Wei在将库移交给社区之前所做的最后一个版本。5.6.2中的问题只是一个潜在的错误,我们偶尔会遇到它们,就像任何其他项目一样。("Wei"bug其实很少见,它们更接近于他的《计算机编程艺术》中的"Knuth"bug)。

如果是5.6.3及以上的问题,那么这意味着社区破坏了它。如果社区破坏了它,那么我们需要进行事后分析,并分析我们如何/为什么设法破坏了曾经有效的东西。

这是库的bug报告:Issue 248: Skip'ing on a Source does not work。我们正在试图确定这是否是一个bug;如果是,那么如何继续。


EDIT 1:我能够更深入地调查这个问题。您可以在评论242890863上阅读分析。简而言之,Skip用于丢弃输出缓冲区 (AttachedTransformation())上的字节,因此在某种程度上按预期工作。然而,没有什么直观的Skip 工作在Source,只工作在附加的Filter (q.v。,我们到了)。

我还在邮件列表中询问了一些反馈问题248:跳过源代码不起作用。DB和WD立即发现了这个问题——这是一个库的设计问题。

这是您目前可以使用的解决方案。实际上,您可以将Pump()转换为null Filter,后者按照预期丢弃输入。然后附加真正的过滤器链来处理真正的处理。

#include <string>
#include <iostream>
using namespace std;
#include <filters.h>
#include <hex.h>
using namespace CryptoPP;
int main(int argc, char* argv[])
{
  string str1, str2;
  HexEncoder enc(new StringSink(str1));
  for(unsigned int i=0; i < 32; i++)
    enc.Put((byte)i);
  enc.MessageEnd();
  cout << "str1: " << str1 <<endl;
  // 'ss' has a NULL AttachedTransformation()
  StringSource ss(str1, false);
  ss.Pump(10);
  // Attach the real filter chain to 'ss'
  ss.Attach(new StringSink(str2));
  ss.PumpAll();
  cout << "str2: " << str2 << endl;
  return 0;
}

它产生预期的输出:

$ ./test.exe 
str1: 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
str2: 05060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F

在您的示例程序中,我认为解决方法是:

FileSource file(filename, false);
file.Pump(24);
file.Attach(new HexEncoder(new StringSink(str)));
file.PumpAll();

EDIT 2:这是一个稍微冗长的方式来实现工作(感谢DB)。它强调字节正在被丢弃。TheBitBucket()只是一个丢弃过滤器,它的作用与null AttachedTransformation()相同。

int main(int argc, char* argv[])
{
  string str1, str2;
  HexEncoder enc(new StringSink(str1));
  for(unsigned int i=0; i < 32; i++)
    enc.Put((byte)i);
  enc.MessageEnd();
  cout << "str1: " << str1 <<endl;
  StringSource ss(str1, false, new Redirector(TheBitBucket()));
  ss.Pump(10);
  ss.Detach(new StringSink(str2));
  ss.PumpAll();
  cout << "str2: " << str2 << endl;
  return 0;
}

上面的程序还有一个微妙的区别:它调用Detach,释放之前的过滤器链。如果调用Attach,则前一个链将被分离,返回给调用者,但不会被释放。