XOR две шестнадцатеричные строки (демаскирование) в C

Я хотел разоблачить шестнадцатеричную строку, используя следующий алгоритм в C j = i MOD 4 преобразованный октет-i = исходный октет-i XOR маскирующий-ключ-октет-j

#include<stdlib.h>
#include<string.h>
int main()
{
    char masked[]="951bfdcdc113ebca921fe9dc";
    char masking_key[]="e17e8eb9";
    char *unmasked;
    int length=strlen(masked);
    unmasked=malloc(sizeof(char)*(length+1));
    int i=0;
    for(i=0;i<length;i++)
    {
       unmasked[i]=masked[i]^masking_key[i%4];
    }
    printf("%s\n",unmasked);
    return 0;
}

Вывод, который я получаю, равен \UT вместо 74657374206d657373616765. Было бы очень полезно, если бы кто-нибудь помог мне исправить ошибку здесь.

Я думаю, что ваши строки действительно должны состоять из шестнадцатеричных кодов символов, а не из шестнадцатеричных чисел. Так что "e17e8eb9" должно быть "\xe1\x7e\x8e\xb9".

M Oehm 17.05.2022 13:12

Вы выполняете xoring ascii-коды шестнадцатеричного вместо xoring фактических чисел.

user253751 17.05.2022 13:14

В стороне: вы выделили один дополнительный, но не написали терминатор строки.

Weather Vane 17.05.2022 13:24
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
3
45
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

То, что вы здесь делаете, - это не xoring шестнадцатеричных байтов, а xor символов, представляющих их.

В то время как идеальным процессом был бы (0x95 ^ 0xe1) + (0xbf ^ 7e) + ..., то, что вы делаете, — это xor значения ascii каждого символа, что означает ('9' ^ 'b') + ('5' ^ '1') + ....

Что вам нужно сделать, так это сначала преобразовать шестнадцатеричную строку в сами байты (bytes.fromhex("951bfdcdc113ebca921fe9dc") в питоне), и только потом их XOR. Я бы сделал это с помощью sscanf("%2x", ...).

Например:

#include <stdio.h>

int main()
{
    unsigned char a = 0;
    scanf("%2hhx", &a);
}
Ответ принят как подходящий

Вам нужно преобразовать из строкового формата в необработанные целые числа, прежде чем выполнять XOR, а затем преобразовать обратно, прежде чем печатать его в виде строки. В противном случае вы будете использовать XOR для значений символов, а не для необработанных значений.

Вы можете преобразовать всю строку за один раз с помощью strtol(data, 0, 16). Но одна из общих деталей, которая отличает программистов от кодовых обезьян, — это возможность кодировать тривиальные преобразования строки в целое число без помощи библиотечных функций. Итак, вот упрощенный код, делающий именно это — имейте в виду полное отсутствие обработки ошибок, так как это просто быстрый и грязный код:

#include <stdio.h>
#include <stdlib.h>

char hexlify (char nibble)
{
  return "0123456789abcdef"[nibble];
}

char unhexlify (char ch)
{
  if(ch>='0' && ch<='9')
    return ch - '0';
  if(ch>='a' && ch<='f')
    return ch - 'a' + 0xA;
  return 0;
}

int main (void)
{
  char masked[]="951bfdcdc113ebca921fe9dc";
  char masking_key[]="e17e8eb9";
  char *unmasked;

  size_t length = sizeof masked - 1;
  unmasked = malloc(length + 1);

  for(size_t i=0;i<length;i++)
  {
    char op1 = unhexlify(masked[i]);
    char op2 = unhexlify(masking_key[i%4]);
    unmasked[i]= hexlify(op1 ^ op2);
  }
  unmasked[length]='\0';

  printf("%s\n",unmasked);
  free(unmasked);
  return 0;
}

Выход:

74651cb3206d0ab4736108a2

(Поскольку вы используете xor по кусочкам, вы должны использовать masking_key[i%8], чтобы получить ожидаемый результат, указанный в вопросе; читается как парные шестнадцатеричные байты, это сообщение в ASCII. Не уверен, откуда берется e в конце.)

M Oehm 17.05.2022 13:47

@MOehm Да, это просто исправление исходного кода OP. Дополнительный вывод был связан с отсутствующей ошибкой нулевого терминатора, которую я исправил, но забыл обновить вывод в посте :)

Lundin 17.05.2022 13:49

Большое спасибо за помощь. Было очень глупо с моей стороны обращаться со строками в C так же, как я обращаюсь с ними в python :).

Manish 17.05.2022 18:55

Другие вопросы по теме