Как отменить операции XOR-сдвига - PullRequest
0 голосов
/ 16 июня 2020

У меня есть следующий кодировщик xor-shift

char a[] = "text";
int b = strlen(a);
for (int c = 0; c < b; c++) {
    if (c > 0) a[c] ^= a[c-1];
    a[c] ^= a[c] >> 3;
    a[c] ^= a[c] >> 2;
    a[c] ^= a[c] >> 1;
    printf("%02x", (unsigned int)(a[c]));
}

Я хотел бы вернуть шестнадцатеричный вывод к исходной строке.

Возможно ли это вообще, учитывая, что сдвиг в некоторых случаях приведет к удалению битов с правой стороны, которые больше нельзя получить? И если это возможно, как можно было отменить операции?

1 Ответ

1 голос
/ 16 июня 2020

Да не так уж и сложно. Просто сопоставьте результаты xor-shit с их исходными значениями. Рассмотрим эту функцию:

char f(char c) {
    c ^= c >> 3;
    c ^= c >> 2;
    c ^= c >> 1;
    return c;
}

Вы должны быть в состоянии убедиться, что для каждого возможного входного значения (от 0 до 127) существует соответствующий уникальный выход. (Конечно, если вы измените char на unsigned char, тогда функция будет работать с любым 8-битным вводом.)

С помощью этой функции вы можете легко создать массив для выполнения обратного действия. function:

char g(char c) {
    static char *map = NULL;
    if (!map) {
        map = malloc(128);
        for (int i=0; i<128; i++) map[f(i)] = i;
    }
    return map[c];
}

Затем просто напишите функцию для чтения каждого символа строки по очереди, примените эту обратную функцию, а затем XOR результата с предыдущим значением:

char *decode(char *s, int len) {
    char *start = s, last = 0;
    while (len--) {
        char tmp = *s;
        *s = last ^ g(*s);
        last = tmp;
        s++;
    }
    return start;
}
...