当前位置: 首页 > 知识库问答 >
问题:

使函数使用std::span而不是旧方法

姜钊
2023-03-14

我刚刚了解到我可以用C++20来使用VS2019并且我正在尝试利用它。我试图使以下函数使用std::span,因为这样data_sizekey_size将是多余的。

除了*datadata++之外,一切正常。它应该是什么?

int rc4(rc4_context* context, const std::uint8_t* data, const std::size_t data_size, const std::uint8_t* key, const std::size_t key_size, std::uint8_t* output)
{
    std::uint32_t i, j;

    // Check parameters
    if (!context || !key)
        return ERROR_INVALID_PARAMETER;

    // Clear context
    context->i = 0;
    context->j = 0;

    // Initialize the S array with identity permutation
    for (i = 0; i < 256; i++)
    {
        context->s[i] = static_cast<std::uint8_t>(i);
    }

    // S is then processed for 256 iterations
    for (i = 0, j = 0; i < 256; i++)
    {
        // Randomize the permutations using the supplied key
        j = (j + context->s[i] + key[i % key_size]) % 256;

        // Swap the values of S[i] and S[j]
        const auto temp = context->s[i];
        context->s[i] = context->s[j];
        context->s[j] = temp;
    }

    // Restore context
    i = context->i;
    j = context->j;
    auto* s = context->s;

    // Encryption loop
    for (size_t x = 0; x < data_size; ++x)
    {
        // Adjust indices
        i = (i + 1) % 256;
        j = (j + s[i]) % 256;

        // Swap the values of S[i] and S[j]
        const auto temp = s[i];
        s[i] = s[j];
        s[j] = temp;

        // Valid input and output?
        if (data && output)
        {
            // XOR the input data with the RC4 stream
            *output = *data ^ s[(s[i] + s[j]) % 256];

            // Increment data pointers
            data++;
            output++;
        }
    }

    // Save context
    context->i = i;
    context->j = j;

    return NO_ERROR;
}
int rc4(rc4_context* context, const std::span<uint8_t*> data, const std::span<std::uint8_t*> key, std::uint8_t* output)
{
    // INITIALIZATION
    std::uint32_t i, j;

    // Check parameters
    if (!context || !key.empty())
        return ERROR_INVALID_PARAMETER;

    // Clear context
    context->i = 0;
    context->j = 0;

    // Initialize the S array with identity permutation
    for (i = 0; i < 256; i++)
    {
        context->s[i] = static_cast<std::uint8_t>(i);
    }

    // S is then processed for 256 iterations
    for (i = 0, j = 0; i < 256; i++)
    {
        // Randomize the permutations using the supplied key
        j = (j + context->s[i] + key[i % key.size()]) % 256;

        // Swap the values of S[i] and S[j]
        const auto temp = context->s[i];
        context->s[i] = context->s[j];
        context->s[j] = temp;
    }

    // MAIN LOGIC PART
    // Restore context
    i = context->i;
    j = context->j;
    auto* s = context->s;

    // Encryption loop
    for (size_t x = 0; x < data.size(); ++x)
    {
        // Adjust indices
        i = (i + 1) % 256;
        j = (j + s[i]) % 256;

        // Swap the values of S[i] and S[j]
        const auto temp = s[i];
        s[i] = s[j];
        s[j] = temp;

        // Valid input and output?
        if (data.empty() && output)
        {
            // XOR the input data with the RC4 stream
            *output = *data ^ s[(s[i] + s[j]) % 256];

            // Increment data pointers
            data++;
            output++;
        }
    }

    // Save context
    context->i = i;
    context->j = j;

    return NO_ERROR;
}

共有1个答案

杭令
2023-03-14

首先,参数对(const std::uint8_t*data,const std::size_t data_size)可以由std::span 代替,而不是std::span

其次,您不需要费心增加data,因为您可以将其重写为基于范围的for循环

for (uint8_t elem : data) {
    // Adjust indices
    i = (i + 1) % 256;
    j = (j + s[i]) % 256;    

    // Swap the values of S[i] and S[j]
    std::swap(s[i], s[j]);

    // Valid output?
    if (output) {
        // XOR the input data with the RC4 stream
        *output++ = elem ^ s[(s[i] + s[j]) % 256];
    }   
}
 类似资料:
  • 我有一节课d::矢量 我计划将成员类型更改为另一种类似于数组的容器类型,只具有足够的功能和较小的内存占用(例如std::experimental::dynarray、std::unique_ptr) 但这破坏了使用常量向量的代码 这将打印0 0,然后崩溃,因为测试it!=end永远不会失败。基于循环的范围当然可以工作,但是这个循环是有效的,因此也必须按照预期工作。我已经预料到,来自同一容器的同一范

  • Item 21 优先使用std::make_unique和std::make_shared而不是直接使用new 我们先给std::make_unique以及std::make_shared提供一个公平的竞争环境,以此开始。std::make_shared是C++ 11标准的一部分,但是,遗憾的是,std::make_unique不是的。它刚成为C++ 14的一部分。如果你在使用C++11.不要怕,

  • 问题内容: 我知道python具有用于确定字符串大小的函数,但是我想知道为什么它不是字符串对象的方法。 更新资料 好吧,我意识到我是一个尴尬的错误。实际上是字符串对象的方法。在字符串对象上使用len函数在Python中看到面向对象的代码似乎很奇怪。此外,看到名字而不是len也很奇怪。 问题答案: 字符串确实有一个length方法: Python中的协议是在具有一定长度并使用内置函数的对象上实现此方

  • 问题内容: Python的Zen指出,只有一种方法可以做事情-但我经常遇到决定何时使用函数以及何时使用方法的问题。 让我们举一个简单的例子- ChessBoard对象。假设我们需要某种方式使董事会上所有合法的King举动均可用。我们写ChessBoard.get_king_moves()还是get_king_moves(chess_board)? 我得到的答案基本上没有定论: 为什么Python使

  • 在 C 中实现回调函数时,我是否仍应使用 C 样式函数指针: 或者我应该使用std::函数:

  • 问题内容: 如果使用方法,则每次通过此方法写入文件时,都会丢失旧数据。是否可以通过写入文件而不会丢失旧数据? 问题答案: 使用采用和的构造函数 并将布尔值设置为。这样,你写入的数据将被附加到文件的末尾,而不是覆盖已经存在的数据。