5

我有两个存储为字符串的十六进制值:

string md5OfPath("a77e0a3e517e0a9d44c3a823d96ca83c");
string guidValue("c3b491e559ac4f6a81e527e971b903ed");

我想对 C++ 中的两个值执行 XOR 操作。您能否建议我如何执行异或操作。

4

6 回答 6

5

我认为直接循环应该可以解决问题:

static inline unsigned int value(char c)
{
    if (c >= '0' && c <= '9') { return c - '0';      }
    if (c >= 'a' && c <= 'f') { return c - 'a' + 10; }
    if (c >= 'A' && c <= 'F') { return c - 'A' + 10; }
    return -1;
}

std::string str_xor(std::string const & s1, std::string const & s2)
{
    assert(s1.length() == s2.length());

    static char const alphabet[] = "0123456789abcdef";

    std::string result;
    result.reserve(s1.length());

    for (std::size_t i = 0; i != s1.length(); ++i)
    { 
        unsigned int v = value(s1[i]) ^ value(s2[i]);

        assert(v < sizeof alphabet);

        result.push_back(alphabet[v]);
    }

    return result;
}
于 2012-10-01T10:41:43.067 回答
2

并行遍历字符串的XOR字符并逐个字符地执行操作,在您遍历它们时将字符附加到结果字符串。

哦,XOR运营商是^

您可以将字符映射到十六进制值:

`0` -> 0x0
`1` -> 0x1
...
`a` -> 0xa

并将^运算符应用于值,而不是字符本身。

于 2012-10-01T10:31:05.770 回答
0

在 C++ 中将两个范围合并为一个的函数式方法是使用std::transform. 在您的情况下,您只需要一个执行 xor 操作的函数对象:

#include <functional>

template <typename T>
struct Xor : std::binary_function<T, T, T> {
    T operator() (T a, T b) {
        return a ^ b;
    }
};

您可以使用它来构造一个对两个字符串中的所有字符进行异或的函数:

#include <cassert>
#include <functional>
#include <iterator>
#include <string>

static std::string xorStrings( const std::string &s1,
                               const std::string &s2 )
{
    std::assert( s1.size() == s2.size() );

    std::string result;
    result.reserve( s1.size() );

    std::transform( s1.begin(), s1.end(),
                    s2.begin(),
                    std::back_inserter( result ),
                    Xor<std::string::value_type>() );

    return result;
}
于 2012-10-01T10:55:04.957 回答
0

可以使用以下函数 (xorTwoHexStrings(string str1, string str2))

#include<sstream>

int hexCharToInt(char a){
    if(a>='0' && a<='9')
        return(a-48);
    else if(a>='A' && a<='Z')
        return(a-55);
    else
        return(a-87);
}

string xorTwoHexStrings(string str1, string str2){
    std::stringstream XORString;
    for(int i=0;i<str2.length();i++){
        XORString << hex << (hexCharToInt(str1[i])^hexCharToInt(str2[i]));
    }
    return XORString.str();
}
于 2014-09-19T00:00:07.517 回答
0

将其拆分为较短的字符串,并按照此答案将每个十六进制字符串转换为整数。然后,您可以对返回的整数数组进行 XOR 或任何您喜欢的操作。

拆分为 4 个字符串应该可以;如果您使用 8 个字符,您将遇到 32 位有符号整数问题(即负数)。

于 2012-10-01T10:46:17.853 回答
0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>

const char* quads[] = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" };

const char * chrTObin(unsigned char c) {
  if(c >= '0' && c <= '9') return quads[     c - '0'];
  if(c >= 'A' && c <= 'F') return quads[10 + c - 'A'];
  if(c >= 'a' && c <= 'f') return quads[10 + c - 'a'];
  return NULL;
  //return -1;
}

char* xorHash(char* chrXOR1, char* chrXOR2) {

    int x;
    int xPos;

    int intXOR1 = strlen(chrXOR1);


    char strBin1[4];
    char strBin2[4];
    char strBin[8];
    char strXORED[4];
    char newXOR[128];

    strcpy(newXOR, "");

    for(x = 0; x < intXOR1; x++) {

        strcpy(strBin, "");
        strcat(strBin, chrTObin(chrXOR1[x]));
        strcat(strBin, chrTObin(chrXOR2[x]));

        strcpy(strXORED, "");

        if(strlen(strBin) == 8) {
            for(xPos = 0; xPos < 4; xPos++) {
                if(strBin[xPos] == strBin[xPos+4]) {
                    strcat(strXORED, "0");
                } else {
                    strcat(strXORED, "1");
                }
            }
        }

        if(strcmp(strXORED, "0000") == 0) {
            strcat(newXOR, "0");
        } else if(strcmp(strXORED, "0001") == 0) {
            strcat(newXOR, "1");
        } else if(strcmp(strXORED, "0010") == 0) {
            strcat(newXOR, "2");
        } else if(strcmp(strXORED, "0011") == 0) {
            strcat(newXOR, "3");
        } else if(strcmp(strXORED, "0100") == 0) {
            strcat(newXOR, "4");
        } else if(strcmp(strXORED, "0101") == 0) {
            strcat(newXOR, "5");
        } else if(strcmp(strXORED, "0110") == 0) {
            strcat(newXOR, "6");
        } else if(strcmp(strXORED, "0111") == 0) {
            strcat(newXOR, "7");
        } else if(strcmp(strXORED, "1000") == 0) {
            strcat(newXOR, "8");
        } else if(strcmp(strXORED, "1001") == 0) {
            strcat(newXOR, "9");
        } else if(strcmp(strXORED, "1010") == 0) {
            strcat(newXOR, "A");
        } else if(strcmp(strXORED, "1011") == 0) {
            strcat(newXOR, "B");
        } else if(strcmp(strXORED, "1100") == 0) {
            strcat(newXOR, "C");
        } else if(strcmp(strXORED, "1101") == 0) {
            strcat(newXOR, "D");
        } else if(strcmp(strXORED, "1110") == 0) {
            strcat(newXOR, "E");
        } else if(strcmp(strXORED, "1111") == 0) {
            strcat(newXOR, "F");
        }

    }

    return newXOR;

}

int main(int argc, char* argv[]) {

    if(argc != 3){
        printf("Usage:\n");
        printf("xor HEX1 HEX2\n");
        return 0;
    }

    if(strlen(argv[1]) == strlen(argv[2])) {

        char oneXOR[128];
        char twoXOR[128];
        char newXOR[128];

        strcpy(oneXOR, argv[1]);
        strcpy(twoXOR, argv[2]);
        strcpy(newXOR, "");

        printf("XOR: %s %s\n", oneXOR, twoXOR);
        strcpy(newXOR, xorHash(oneXOR, twoXOR));
        printf("RESULT: %s\n", newXOR);

    }

    return 0;
}
于 2017-02-16T21:16:09.990 回答