ruipacheco
ruipacheco

Reputation: 16452

How can I xor the content of these two vectors?

I have two vectors of unsigned chars:

std::vector<uint8_t> a = {'\xac', '\xf9', '\xe1', 'o', 'R', '5', 'M', '\x9b', '\x13', 'I', '2', '%', 'W', ',', '\xd0', 't', '\xde', '\x94', '\xb3', '+'};

and

std::vector<uint8_t> b =  {'7','\x8e',';','\xca','\xc6','\xc7','B','b','x','z','\x89','i','P','\xa3','%','\x86','\xdb','^','\xdb','\x9f'};

How can I xor the contents of these vectors? Can I just cast them to int?

Upvotes: 1

Views: 8442

Answers (5)

Marco A.
Marco A.

Reputation: 43662

I'm assuming your vectors are of equal size (if I understood what you intend to do correctly)

Quite easy:

// Xor every couple of elements and store results in `a`
std::transform(a.begin(), a.end(), b.begin(),
    a.begin(), std::bit_xor<uint8_t>()); // std::bit_xor defined in <functional>

(equivalent to)

std::transform(a.begin(), a.end(), b.begin(),
    a.begin(), [](auto e1, auto e2) {
    return e1 ^ e2;
});

Live Example

Ben's std::valarray suggestion is another nice way of doing it.

Upvotes: 4

Richard Hodges
Richard Hodges

Reputation: 69902

boost zip iterators can help:

#include <iostream>
#include <iomanip>
#include <vector>
#include <boost/iterator/zip_iterator.hpp>

void show(std::vector<uint8_t>const& result);

std::vector<uint8_t> a = {'\xac', '\xf9', '\xe1', 'o', 'R', '5', 'M', '\x9b', '\x13', 'I', '2', '%', 'W', ',', '\xd0',
                          't', '\xde', '\x94', '\xb3', '+'};
std::vector<uint8_t> b = {'7', '\x8e', ';', '\xca', '\xc6', '\xc7', 'B', 'b', 'x', 'z', '\x89', 'i', 'P', '\xa3', '%',
                          '\x86', '\xdb', '^', '\xdb', '\x9f'};

int main() {
    std::vector<uint8_t> result;

    auto Xor = [](auto const& xy) { return boost::get<0>(xy) ^ boost::get<1>(xy); };
    auto first = boost::make_zip_iterator(boost::make_tuple(a.begin(), b.begin()));
    auto last = boost::make_zip_iterator(boost::make_tuple(a.end(), b.end()));

    std::transform(first, last,
                   std::back_inserter(result),
                   Xor);

    show(result);

}

void show(std::vector<uint8_t>const& result)
{
    const char *sep = "";
    for (uint8_t n : result) {
        std::cout << sep << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(n);
        sep = ", ";
    }
    std::cout << std::endl;
}

Upvotes: 0

Ben Voigt
Ben Voigt

Reputation: 283733

I recommend that you use std::valarray<T> instead of std::vector<T> for this, it already defines all the bitwise and arithmetic operators in their elementwise way.

Then your data would be

#include <valarray>

std::valarray<uint8_t> a = { 0xacu, 0xf9u, 0xe1u, 'o', 'R', '5', 'M', 0x9bu, 0x13u, 'I', '2', '%', 'W', ',', 0xd0u, 't', 0xdeu, 0x94u, 0b3u, '+'};
std::valarray<uint8_t> b =  {'7', 0x8eu, ';', 0xcau, 0xc6u, 0xc7u, 'B', 'b', 'x', 'z', 0x89u, 'i', 'P', 0xa3u, '%', 0x86u, 0xdbu, '^', 0xdbu, 0x9fu};

and XOR would be simply

auto c = a ^ b;

Upvotes: 5

eerorika
eerorika

Reputation: 238401

How can I xor the contents of these vectors?

You can use the following algorithm:

let c be a new vector of same size as a and b
for i in [0 .. a.size()[
    c[i] = a[i]^b[i]

Upvotes: 0

R Sahu
R Sahu

Reputation: 206697

How can I xor the contents of these vectors?

Each element of the vectors is an integral type. You can use:

uint8_t res = a[i] ^ b[i];

Can I just cast them to int?

You can, but there is no need. All integral types can be used as operands of the ^ operator.

Upvotes: 2

Related Questions