我正在实现一个自定义 iostream(即具有读、写、查找和关闭功能),它使用 RC4 流密码进行加密和解密。此流的契约之一是它是双向的,调用代码需要能够在进行任何实际读取或写入之前任意查找流中的任何位置。
现在,因为 RC4 使用的 key 依赖于所有先前的交换操作,直到给定的“告诉”位置,我如何才能合并任意搜索到任何位置的能力?
显然,在执行实际的异或转换过程之前,我可以查找到给定查找偏移量的位置(在以下示例中标记为 THIS BIT) ,类似的东西:
/**
* @brief called from a stream's read or write function
* @param in the input buffer
* @param out the output buffer
* @param startPosition the current stream position (obtained via the streams
* tellg or tellp functions for read and write respectively)
* @param length the number of bytes to transform
*/
void transform(char *in, char *out,
std::ios_base::streamoff startPosition,
long length)
{
// need to reset sbox from member s_box each time this
// function is called
long sbox[256];
for (int i = 0; i<256; ++i) {
sbox[i]=m_sbox[i];
}
// ***THIS BIT***
// need to run the swap operation startPosition times
// to get sbox integer sequence in order
int i = 0, j = 0, k = 0;
for (int a=0; a < startPosition; ++a) {
i = (i + 1) % 256;
j = (j + sbox[i]) % 256;
swapints(sbox, i, j);
}
// now do the actual xoring process up to the length
// of how many bytes are being read or written
for (int a=0; a < length; ++a) {
i = (i + 1) % 256;
j = (j + sbox[i]) % 256;
swapints(sbox, i, j);
k = sbox[(sbox[i] + sbox[j]) % 256];
out[a] = in[a] ^ k;
}
}
然后转换将从流实现的读取或写入中调用,类似于:
MyStream&
MyStream::read(char * const buf, std::streamsize const n)
{
std::ios_base::streamoff start = m_stream.tellg();
std::vector<char> in;
in.resize(n);
(void)m_stream.read(&in.front(), n);
m_byteTransformer->transform(&in.front(), buf, start, n);
return *this;
}
编辑:流应该不知道转换函数是如何工作的。转换功能是完全独立的,我应该能够在不同的转换实现中自由切换。
编辑:函数 swapints 如下所示:
void swapints(long *array, long ndx1, long ndx2)
{
int temp = array[ndx1];
array[ndx1] = array[ndx2];
array[ndx2] = temp;
}
上述转换函数的真正问题在于它的缓慢,因为它必须在执行异或转换之前执行 startPosition 初始交换操作。当执行许多查找操作时,这是非常有问题的。现在我听说 RC4 是为了快速,但我的(可能是糟糕的实现)建议在给定初始交换操作集的情况下否则。
所以我真正的问题是:如何优化上述代码以减少所需操作的数量?理想情况下,我想消除初始的(“THIS BIT”)一组交换操作
编辑:优化初始 sbox 设置可能是微不足道的(例如,按照 egur 的建议使用 memcpy)。我认为重要的优化是如何优化由 THIS BIT 标记的循环。也许所有这些交换整数都可以更简洁地编程,而不需要 for 循环。
谢谢,
本
最佳答案
将所有 % 255
更改为 & 0xff
,速度更快:
i = (i + 1) % 256;
收件人:
i = (i + 1) & 0xFF;
编辑:
您在初始化 sbox
上浪费了很多时间。您应该将 sbox
作为参数传递给转换函数,以便在调用之间更新原始拷贝。你现在正在做的是一次又一次地初始化它,每次它都会花费更长的时间,因为 startPosition 增长。
void transform(char *in, char *out,
long length,
unsigned char* sbox)
临时sbox
应该是MyStream
类的成员。读取函数应该是:
MyStream&
MyStream::read(char * const buf, std::streamsize const n)
{
std::ios_base::streamoff start = m_stream.tellg();
std::vector<char> in;
in.resize(n);
(void)m_stream.read(&in.front(), n);
// init m_TempSbox on first call
if (m_FirstCall) {
initTempSbox();
}
m_byteTransformer->transform(&in.front(), buf, n, m_TempSbox);
return *this;
}
关于c++ - 编写使用 RC4 流密码的 C++ iostream。如何优化我的实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21112360/