首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Citadel的VisualEncrypt和VisualDecrypt

Citadel的VisualEncrypt和VisualDecrypt
EN

Code Review用户
提问于 2014-07-18 22:08:18
回答 2查看 363关注 0票数 10

出于无聊,我浏览了一下本论文。在第5页和第6页,本文展示了Citadel用来混淆数据的简单加密/解密方案。该算法基本上是XOR下一个字符与前一个字符。代码大致如下(我知道,很难看):

{ for (无符号I= 1;i< size;++i) {(无符号字符*)缓冲区) 我 ^= ((无符号字符*)缓冲区) 一-一;}} VisualDecrypt (空白*缓冲区,无符号大小){ if (! size ) {返回;} for (无符号I=大小- 1;i> 0;--i) {(无符号字符*)缓冲区) 我 ^= ((无符号字符*)缓冲区) 一-一;}

我决定对这段代码做一个更通用的版本,以便它可以在不同的容器和值上工作:

代码语言:javascript
复制
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) ;
}

下面是使用它的两个示例:

代码语言:javascript
复制
#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>库来简化这一切。任何关于这方面的建议也会很棒。

EN

回答 2

Code Review用户

回答已采纳

发布于 2014-07-20 06:11:40

将第一个元素作为特例处理的方式非常麻烦:您基本上是在展开循环的第一次迭代。您只需初始化value = 0,以便第一个XOR只将输入复制到输出。

代码语言:javascript
复制
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-循环,这会使代码稍微紧凑一些,并消除讨厌的副作用++操作符。

代码语言:javascript
复制
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;
}
票数 7
EN

Code Review用户

发布于 2014-07-21 15:36:32

根据@vnp的建议使用std::transform和@200_success的简化,我们可以创建两个函数对象。

加密程序:

代码语言:javascript
复制
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 ;
    }
};

以及解密程序:

代码语言:javascript
复制
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()函数变成了普通的两行程序:

代码语言:javascript
复制
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> ()) ;
}

这些加密和解密函数签名可以扩展为接受任何加密/解密函数对象:

代码语言:javascript
复制
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()

票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/57420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档