Как вы выполняете операцию XOR для длинного целого числа без знака и массива символов в C?

#c

#c

Вопрос:

Это мои две переменные, с которыми я хочу выполнить операцию xor (в C).

 unsigned long int z=0xB51A06CD;

unsigned char array[] = {0xF0,0xCC,0xAA,0xF0};

desired output= 0X45D6AC3D
 

Я знаю, что не могу выполнить простое z ^ array , потому что это массив символов, а не один символ. Должен ли я выполнять XOR по одному байту за раз или для этого есть функция в C?

Я пробую всевозможные сумасшедшие вещи, чтобы сделать это, но все время терплю неудачу. Если кто-нибудь может помочь мне с небольшим фрагментом кода или хотя бы приблизительной идеей, я был бы чрезвычайно благодарен.

Комментарии:

1. Нет специальной функции, вы должны делать это по одному символу за раз. Если вы не уверены в конечном порядке.

Ответ №1:

Приведите значение array , которое рассматривается как указатель на первый элемент в выражении, подобном этому, к длинному указателю вместо указателя char и разыменуйте его.

 unsigned long result = z ^ *(unsigned long *)array;
 

Комментарии:

1. Это опасно; вы не знаете, что массив байтов соответствующим образом выровнен для unsigned long .

2. Вероятно, очевидное предупреждение, но при приведении убедитесь, что порядок байтов и порядковый номер указаны правильно. Если OP контролирует содержимое массива, это не должно быть проблемой. Если оно поступает из внешнего источника (COMM-порт, сокет и т. Д.), Все ставки могут быть отменены.

3. Плюс символы в C # являются юникодом, поэтому значение, которое вы вводите, на самом деле будет 0x00f000aa00cc00f0

Ответ №2:

Просто сделайте unsigned long int из своего массива (внимание, это зависит от порядкового номера машины!):

 unsigned long int z=0xB51A06CD;
unsigned char array[] = {0xF0,0xCC,0xAA,0xF0};

unsigned long int w = 0;
w |= array[0] << 0;
w |= array[1] << 8;
w |= array[2] << 16;
w |= array[3] << 24;

unsigned long output = z ^ w;
 

Комментарии:

1. Это не зависит от порядкового номера машины, вы просто сделали это неправильно. Желаемый результат спрашивающего указывает, что array[1] он должен быть сдвинут на 16, а не на 8, поскольку 0x1A ^ 0xCC == 0xD6 .

Ответ №3:

 unsigned long int z=0xB51A06CD;

unsigned char array[] = {0xF0,0xCC,0xAA,0xF0};
unsigned long tmp;
memcpy(amp;tmp, array, sizeof tmp);
... z ^ tmp ...
 

Обратите внимание, что это все еще делает ряд непереносимых предположений: это unsigned long 4 байта, и что порядковый номер системы соответствует вашим ожиданиям.

Комментарии:

1. Либо мой ответ, либо ответ @K-ballo может быть более полезным, в зависимости от того, как вы хотите решить проблему с порядком следования. Конкретные требования не ясны из вопроса.

Ответ №4:

Как упоминали другие, вам нужно беспокоиться о порядке следования и размере long . Вот как сделать это безопасным: 1) вместо unsigned long используйте uint32_t (из inttypes.h), чтобы убедиться, что вы получаете 4-байтовый тип. 2) используйте htonl() в качестве независимого от платформы способа, чтобы убедиться, что вы интерпретируете массив как значение с большим порядком

 z ^ htonl(*(uint32_t *)array);