跳过源无法按预期工作

Skip'ing on a Source does not work as expected

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

这是一个例子 function

string filename = ...;
string str;

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

有人可以帮助我吗?

I use Crypto++ 5.6.3 and iI need the FileSource "skip(...) function. Unfortunately this function does nothing!

我能够在 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" 错误实际上是很少见的,它们更接近他 Art of Computer Programming 中的 "Knuth" 错误)。

如果是5.6.3及以上版本的问题,那就说明社区坏了。如果社区破坏了它,那么我们需要执行 post-mortem 并分析 how/why 我们设法破坏了曾经有效的东西。

这是库的错误报告:Issue 248: Skip'ing on a Source does not work。我们正在尝试确定它是否是错误;如果是,那么如何进行。


编辑 1:我能够进一步调查这个问题。您可以在 Comment 242890863 阅读分析。简而言之,Skip 用于丢弃 输出缓冲区 AttachedTransformation())上的字节,所以事情 有点 按预期工作。但是,关于 Skip notSource 上工作并仅在附加的 Filter 上工作(q.v.,我们来了).

我还在 Issue 248: Skip'ing on a Source does not work 的邮件列表中征求了一些反馈意见。 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,那么前一个链将被分离,返回给调用者但不会被释放。