出于无聊,我浏览了一下本论文。在第5页和第6页,本文展示了Citadel用来混淆数据的简单加密/解密方案。该算法基本上是XOR下一个字符与前一个字符。代码大致如下(我知道,很难看):
{ for (无符号I= 1;i< size;++i) {(无符号字符*)缓冲区) 我 ^= ((无符号字符*)缓冲区) 一-一;}} VisualDecrypt (空白*缓冲区,无符号大小){ if (! size ) {返回;} for (无符号I=大小- 1;i> 0;--i) {(无符号字符*)缓冲区) 我 ^= ((无符号字符*)缓冲区) 一-一;}
我决定对这段代码做一个更通用的版本,以便它可以在不同的容器和值上工作:
template <class InputIterator, class OutputIterator>
OutputIterator VisualEncrypt (InputIterator begin, InputIterator end, OutputIterator destination)
{
if (begin == end) {
return destination ;
}
auto value = *begin ;
*destination++ = value ;
while (++begin != end) {
value ^= *begin ;
*destination++ = value ;
}
return destination ;
}
template <class InputIterator, class OutputIterator>
OutputIterator VisualDecrypt (InputIterator begin, InputIterator end, OutputIterator destination)
{
if (begin == end) {
return destination ;
}
auto value = *begin ;
*destination++ = value ;
while (++begin != end) {
auto temp = *begin ;
*destination++ = value ^ temp ;
value = temp ;
}
return destination ;
}
template <class Iterator>
Iterator VisualEncrypt (Iterator begin, Iterator end)
{
return VisualEncrypt (begin, end, begin) ;
}
template <class Iterator>
Iterator VisualDecrypt (Iterator begin, Iterator end)
{
return VisualDecrypt (begin, end, begin) ;
}下面是使用它的两个示例:
#include <iterator>
#include <string>
#include <vector>
int main ()
{
// Test char
std::string plaintext = "Please encrypt me!" ;
std::vector <unsigned char> cyphertext ;
VisualEncrypt (plaintext.cbegin (), plaintext.cend (), std::back_inserter (cyphertext)) ;
std::string decrypttext ;
VisualDecrypt (cyphertext.cbegin (), cyphertext.cend (), std::back_inserter (decrypttext)) ;
// Test long
long arr [] = {1, 2, 3, 4, 5} ;
const auto size = sizeof (arr) / sizeof (arr [0]) ;
VisualEncrypt (arr, arr + size) ;
VisualDecrypt (arr, arr + size) ;
return 0 ;
}代码似乎很好用。我想确保我没有误用迭代器和调用未定义的行为。我找不到一种干净的方法来用<algorithm>库来简化这一切。任何关于这方面的建议也会很棒。
发布于 2014-07-20 06:11:40
将第一个元素作为特例处理的方式非常麻烦:您基本上是在展开循环的第一次迭代。您只需初始化value = 0,以便第一个XOR只将输入复制到输出。
template <class InputIterator, class OutputIterator>
OutputIterator VisualEncrypt (InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits<InputIterator>::value_type T;
T value = 0;
while (begin != end) {
value ^= *begin++;
*destination++ = value ;
}
return destination ;
}
template <class InputIterator, class OutputIterator>
OutputIterator VisualDecrypt (InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits<InputIterator>::value_type T;
T value = 0;
while (begin != end) {
T temp = *begin++;
*destination++ = value ^ temp ;
value = temp ;
}
return destination ;
}或者,使用for-循环,这会使代码稍微紧凑一些,并消除讨厌的副作用++操作符。
template <class InputIterator, class OutputIterator>
OutputIterator VisualEncrypt(InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits<InputIterator>::value_type T;
for (T value = 0; begin != end; ++begin, ++destination) {
*destination = (value ^= *begin); // <-- Probably controversial one-liner
}
return destination;
}
template <class InputIterator, class OutputIterator>
OutputIterator VisualDecrypt(InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits<InputIterator>::value_type T;
for (T value = 0; begin != end; ++begin, ++destination) {
T temp = *begin;
*destination = value ^ temp;
value = temp;
}
return destination;
}发布于 2014-07-21 15:36:32
根据@vnp的建议使用std::transform和@200_success的简化,我们可以创建两个函数对象。
加密程序:
template <typename T>
struct Encrypt
{
typedef T value_type ;
value_type value ;
Encrypt () : value (0)
{
}
value_type operator () (const value_type &input) {
value ^= input ;
return value ;
}
};以及解密程序:
template <typename T>
struct Decrypt
{
typedef T value_type ;
value_type value ;
Decrypt () : value (0)
{
}
value_type operator () (const value_type &input) {
value_type temp = value ;
value = input ;
return temp ^ input ;
}
};然后,VisualEncrypt()和VisualDecrypt()函数变成了普通的两行程序:
template <class InputIterator, class OutputIterator>
OutputIterator VisualEncrypt(InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits<InputIterator>::value_type value_type ;
return std::transform (begin, end, destination, Encrypt <value_type> ()) ;
}
template <class InputIterator, class OutputIterator>
OutputIterator VisualDecrypt(InputIterator begin, InputIterator end, OutputIterator destination)
{
typedef typename std::iterator_traits<InputIterator>::value_type value_type ;
return std::transform (begin, end, destination, Decrypt <value_type> ()) ;
}这些加密和解密函数签名可以扩展为接受任何加密/解密函数对象:
template <class InputIterator, class OutputIterator, class EncryptOp>
OutputIterator VisualEncrypt(InputIterator begin, InputIterator end, OutputIterator destination, EncryptOp encrypt_op)
{
return std::transform (begin, end, destination, encrypt_op) ;
}
template <class InputIterator, class OutputIterator, class DecryptOp>
OutputIterator VisualDecrypt(InputIterator begin, InputIterator end, OutputIterator destination, DecryptOp decrypt_op)
{
return std::transform (begin, end, destination, decrypt_op) ;
}但是,如果您这样做,您可能还不如单独使用std::transform()。
https://codereview.stackexchange.com/questions/57420
复制相似问题