Solution to the Grand Arcane Codex Challenge

Problem Prompt:

The Grand Arcane Codex has been corrupted, altering historical records. Each entry has been encoded with an enchanted shifting cipher that encrypts a plaintext composed of 3-7 randomly generated words.

The cipher operates as follows:

  • Alphabetical characters are processed in groups of 5 (ignoring non-alphabetical characters).
  • For each group, a random shift between 1 and 25 is chosen and applied to every letter in that group.
  • After the encoded message, an additional line indicates the total number of shift groups, followed by another line listing the random shift values used for each group.

Your quest is to decode the given input and restore the original plaintext.

Example Input:


ibeqtsl 2 [4, 7]

Example Output:


example

Solution (C Code):

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

char *decode_message(char *encoded_message, int *shifts, int num_groups) {
int len = strlen(encoded_message);
char *alpha_chars = (char *)malloc(len + 1);
int alpha_index = 0;
for (int i = 0; i < len; i++) {
if (isalpha(encoded_message[i])) {
alpha_chars[alpha_index++] = tolower(encoded_message[i]);
}
}
alpha_chars[alpha_index] = '\0';

char *decoded_alpha = (char *)malloc(alpha_index + 1);
int decoded_index = 0;
int shift_group = 0;
int char_in_group = 0;

for (int i = 0; i < alpha_index; i++) {
int current_shift = shifts[shift_group];
int original_char_index = alpha_chars[i] - 'a';
int decoded_char_index = (original_char_index - current_shift + 26) % 26;
decoded_alpha[decoded_index++] = decoded_char_index + 'a';
char_in_group++;
if (char_in_group == 5) {
shift_group++;
char_in_group = 0;
} else if (i == alpha_index - 1) {
shift_group++;
}
if (shift_group >= num_groups) {
break;
}
}
decoded_alpha[decoded_index] = '\0';

char *decoded_message = (char *)malloc(len + 1);
int decoded_msg_index = 0;
int decoded_alpha_counter = 0;
for (int i = 0; i < len; i++) {
if (isalpha(encoded_message[i])) {
decoded_message[decoded_msg_index++] = decoded_alpha[decoded_alpha_counter++];
} else {
decoded_message[decoded_msg_index++] = encoded_message[i];
}
}
decoded_message[decoded_msg_index] = '\0';

free(alpha_chars);
free(decoded_alpha);
return decoded_message;
}

int main() {
char encoded_message[1000];
int num_groups;
char shifts_str[200];

fgets(encoded_message, sizeof(encoded_message), stdin);
encoded_message[strcspn(encoded_message, "\n")] = 0;

scanf("%d", &num_groups);
getchar();

fgets(shifts_str, sizeof(shifts_str), stdin);
shifts_str[strcspn(shifts_str, "\n")] = 0;

int shifts[num_groups];
char *token = strtok(shifts_str, "[, ]");
int i = 0;
while (token != NULL && i < num_groups) {
shifts[i++] = atoi(token);
token = strtok(NULL, "[, ]");
}

char *decoded_output = decode_message(encoded_message, shifts, num_groups);
printf("%s\n", decoded_output);
free(decoded_output);

return 0;
}

An image to describe post
Flag:

HTB{3NCH4NT3D_C1PH3R_D3C0D3D_b97bdda110d2c41b5f9d1005cabddb14}