Помогите обернуть цикл вспять

Ответить

Код подтверждения
Введите код в точности так, как вы его видите. Регистр символов не имеет значения.

BBCode ВКЛЮЧЁН
[img] ВКЛЮЧЁН
[url] ВКЛЮЧЁН
Смайлики ОТКЛЮЧЕНЫ

Обзор темы
   

Развернуть Обзор темы: Помогите обернуть цикл вспять

Re: Помогите обернуть цикл вспять

Skwoogey » 04 апр 2018, 20:17

Так ранд по сути роли не играет. Он там просто так чтобы процессору без дела не сидеть.

Код: Выделить всё

    int b = a1(rand()) % 0xffff; //b = ...xxxxxxxx
 
    b <<= 4; //b = ...xxxx0000
    b ^= (k[(t++) % ss] >> 4); //b = ...xxxxssss s - что-то что можно однозначно расчитать
    b <<= 4; //b = ...ssss0000
    b ^= (k[(t++) % ss]); //b = ...ssssssss
 
    a ^= (char)b; //используем только последние 8 бит
Не помешало бы переменные и функции называть понятнее.

Вообще массив k весьма интересная структура. Он определен через дефайн, то есть является литералом строки, а потом мы от литерала берем конкретный элемент. Оно так работает?

Кстати, то что она выдает один и тот же результат не значит, что она обратима.

Можно узнать откуда алгоритм шифрования? Мне кажется, что он не полный, так как мы шифруем только первые 64 байта (Вероятно это блочный алгоритм шифрования, не запущенный в цикл). Также если это известный алгоритм шифрования, то для него скорее всего есть алгоритм дешифровки. Визуально мы его ксорим байты между собой и чем-то другим кучу раз и, конечно, можно попытаться отследить для каждого элемента, что получается, а потом попробовать подобрать формулы для расшифровки, но это долго, муторно и не факт, что сработает.

Re: Помогите обернуть цикл вспять

Romeo » 03 апр 2018, 00:06

Absurd, внимательней. Там seed сбрасывается через time, как положено :)

Re: Помогите обернуть цикл вспять

Absurd » 02 апр 2018, 23:28

Absurd писал(а):Если seed один и тот же, то rand даст одинаковую цепочку значений.

А так, есть генераторы псевдослучайных чисел которые можно мотать в обратном порядке. Стандартный сишный вроде нельзя.

Re: Помогите обернуть цикл вспять

Absurd » 02 апр 2018, 23:20

Romeo писал(а):Ты понимаешь, что зашифровать можно так, что потом не расшифруешь? Именно поэтому в криптографии разделяют алгоритмы на обратимые и необратимые. Если мы внимательно посмотрим в функцию f1, то увидим там использование rand(). Это приводит нас к однозначному выводу - данный алгоритм необратим, так как мы не знаем какие числа вернула функция rand() на этапе шифровки.

Если seed один и тот же, то rand даст одинаковую цепочку значений.

Re: Помогите обернуть цикл вспять

Romeo » 02 апр 2018, 19:52

Сомневаюсь, что одно и то же значение выдаёт. Значение, которое возвращается rand() активно используется дальше. Игнора нет. Я проверю дома.

Но даже если вдруг окажется, что это так, то этого не достаточно, чтобы преобразование было обратимым. Необходимое и достаточное условие обратимости - это взаимно однозначность преобразования. Судя по формулам, взаимно однозначности тут как раз нет.

Re: Помогите обернуть цикл вспять

shwwawaw » 02 апр 2018, 17:56

Romeo писал(а):Ты понимаешь, что зашифровать можно так, что потом не расшифруешь? Именно поэтому в криптографии разделяют алгоритмы на обратимые и необратимые. Если мы внимательно посмотрим в функцию f1, то увидим там использование rand(). Это приводит нас к однозначному выводу - данный алгоритм необратим, так как мы не знаем какие числа вернула функция rand() на этапе шифровки.

Она обратима
Я тестил раз 100
Она выдает один результат
Там в функции еще приведение к char
Короче это хм.. для отвлечения внимания видимо.

Re: Помогите обернуть цикл вспять

Romeo » 02 апр 2018, 16:32

Ты понимаешь, что зашифровать можно так, что потом не расшифруешь? Именно поэтому в криптографии разделяют алгоритмы на обратимые и необратимые. Если мы внимательно посмотрим в функцию f1, то увидим там использование rand(). Это приводит нас к однозначному выводу - данный алгоритм необратим, так как мы не знаем какие числа вернула функция rand() на этапе шифровки.

Re: Помогите обернуть цикл вспять

shwwawaw » 02 апр 2018, 11:20

Romeo писал(а):Выкладывай свою попытку. Будем разбираться, что не так.

Код: Выделить всё

#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <stdio.h>
#define k "jf1ay9238x0ax0"
char f1(char a);
int a1(int a);
 
int main()
{
    srand(time(0));
 
    printf("Enter path:");
    fflush(stdout);
    char p[64];
    scanf("%s", p);
    char c;
    do {
        c = getchar();
    } while (c != '\n' && c != EOF);
 
    FILE* f = fopen(p, "rb");
    if (f == NULL) {
        printf("Error opening file");
        getch();
        exit(-3);
    }
    char m[64];
    fread(&m, sizeof(char), 64, f);
    fclose(f);
 
    printf("%s\n", p);
    printf("Cipher?(Y/n):");
    fflush(stdout);
    char r;
    scanf("%c", &r);
    do {
        c = getchar();
    } while (c != '\n' && c != EOF);
    char ot = r;
 
    if (ot == 'Y') {
        char s = 0;
        for (int i = 0; i < 64; ++i) {
            s ^= m[i];
        }
 
        for (int i = 0; i < 63; ++i) {
            m[i] ^= (m[i + 1] ^ s^r^i ^ ((0xf) << 4) ^ ((i % 2) << 7));
            m[i] = f1(m[i]);
        }
        m[63] ^= s;
 
        FILE* f = fopen("out.txt", "wb");
        fputc(s, f);
        fwrite(m, sizeof(char), 64, f);
        fclose(f);    
    }

/*
Вот отсюда начинаем процесс
В обратную сторону
типа Xor x2 = text
/*
	printf("Enter path:");
    fflush(stdout);
/* Чтобы не париться
переназначил переменный добавив 
к ним 0
*/
    char p0[64];
    scanf("%s", p0);
    char c0;
    do {
        c0 = getchar();
    } while (c0 != '\n' && c0 != EOF);
 
    FILE* f0 = fopen(p0, "rb");
    if (f0 == NULL) {
        printf("Error opening file");
        getch();
        exit(-3);
    }
    char m0[64];
    fread(&m0, sizeof(char), 64, f0);
    fclose(f0);
 
    printf("%s\n", p0);
    printf("UNNCipher?(Y/n):");
    fflush(stdout);
    char r0;
    scanf("%c", &r0);
    do {
        c0 = getchar();
    } while (c0 != '\n' && c0 != EOF);
    char ot0 = r0;
 
    if (ot0 == 'Y') {
/* И вот здесь уже не понял
В исходной проге S 
это ХОР всего текса побайтно
и потом последний байт мы еще ксорим
этим S
т.е. перебрав 256 вариантов один из них будет
верным ключем
*/
        char s0;
    scanf("%c", &s0);
/* Этот цикл тогда вообще нужен? 
поидее - да
*/
// берем последний байт, дексорим

 m0[63] ^= s0;
// Потом цикл в обратную сторону
for (int i = 62; i >= 0; --i) {
// Вот здесь я так и не осознал
// какое именно значение играет f1 функция
m0[i] = f1(m0[i]);
m0[i] ^= (m0[i + 1] ^ s0^r0^i ^ ((0xf) << 4) ^ ((i % 2) << 7));

        }

        for (int i = 63; i >=; ++i) {
            s0 ^= m0[i];
        }
 
        FILE* f = fopen("out.txt", "wb");
        fputc(s, f);
        fwrite(m, sizeof(char), 64, f);
        fclose(f);    
    }
	
    return 0;
}
char f1(char a)
{
    char ss = 0xd;
    static int t = 0;
    int b = a1(rand()) % 0xffff;
 
    b <<= 4;
    b ^= (k[(t++) % ss] >> 4);
    b <<= 4;
    b ^= (k[(t++) % ss]);
 
    a ^= (char)b;
    return a;
}
 
int a1(int a) {
    if (a < 0)
        return (-a);
    else
        return a;
}
Вот примерно как-то так.
Хз, я понимаю, что где-то косячу, но голова очень плохо усваивает подобные выкидоны
поэтому обратился за помощью

Re: Помогите обернуть цикл вспять

Romeo » 02 апр 2018, 08:43

Выкладывай свою попытку. Будем разбираться, что не так.

Помогите обернуть цикл вспять

shwwawaw » 02 апр 2018, 08:18

Доброго времени суток. Помогите решить одну проблему
у меня есть программа следующего вида:

Код: Выделить всё

#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <stdio.h>
#define k "jf1ay9238x0ax0"
char f1(char a);
int a1(int a);

int main()
{
    srand(time(0));

    printf("Enter path:");
    fflush(stdout);
    char p[64];
    scanf("%s", p);
    char c;
    do {
        c = getchar();
    } while (c != '\n' && c != EOF);

    FILE* f = fopen(p, "rb");
    if (f == NULL) {
        printf("Error opening file");
        getch();
        exit(-3);
    }
    char m[64];
    fread(&m, sizeof(char), 64, f);
    fclose(f);

    printf("%s\n", p);
    printf("Cipher?(Y/n):");
    fflush(stdout);
    char r;
    scanf("%c", &r);
    do {
        c = getchar();
    } while (c != '\n' && c != EOF);
    char ot = r;

    if (ot == 'Y') {
        char s = 0;
        for (int i = 0; i < 64; ++i) {
            s ^= m[i];
        }

        for (int i = 0; i < 63; ++i) {
            m[i] ^= (m[i + 1] ^ s^r^i ^ ((0xf) << 4) ^ ((i % 2) << 7));
            m[i] = f1(m[i]);
        }
        m[63] ^= s;

        FILE* f = fopen("out.txt", "wb");
        fputc(s, f);
        fwrite(m, sizeof(char), 64, f);
        fclose(f);    
    }

    return 0;
}
char f1(char a)
{
    char ss = 0xd;
    static int t = 0;
    int b = a1(rand()) % 0xffff;

    b <<= 4;
    b ^= (k[(t++) % ss] >> 4);
    b <<= 4;
    b ^= (k[(t++) % ss]);

    a ^= (char)b;
    return a;
}

int a1(int a) {
    if (a < 0)
        return (-a);
    else
        return a;
}
Её суть в том, что она читает побайтно файл с текстом, а затем хорит его по определенному алгоритму и записывает в другой файл.
В общем суть моего вопроса:
помогите написать реверсирующую процедуру, т.е. чтобы подавая на вход зашифрованное сообщение получался исходный читаемый текст.
Всю голову себе уже исколупал, 10 раз прошел по алгоритму, но все равно где-то я что-то упускаю (может сдвиг может еще что)
И да, я знаю, что 2х xor дает исходный результат.

Спасибо большое заранее тем, кто откликнется =)

Вернуться к началу