#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);