+ Ответить в теме
Показано с 1 по 10 из 10

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

  1. #1
    dummy shwwawaw is on a distinguished road
    Регистрация
    02.04.2018
    Возраст
    20
    Сообщений
    3
    Вес репутации
    0

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

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

    Код cpp:
    1. #include <stdlib.h>
    2. #include <conio.h>
    3. #include <time.h>
    4. #include <stdio.h>
    5. #define k "jf1ay9238x0ax0"
    6. char f1(char a);
    7. int a1(int a);
    8.  
    9. int main()
    10. {
    11.     srand(time(0));
    12.  
    13.     printf("Enter path:");
    14.     fflush(stdout);
    15.     char p[64];
    16.     scanf("%s", p);
    17.     char c;
    18.     do {
    19.         c = getchar();
    20.     } while (c != '\n' && c != EOF);
    21.  
    22.     FILE* f = fopen(p, "rb");
    23.     if (f == NULL) {
    24.         printf("Error opening file");
    25.         getch();
    26.         exit(-3);
    27.     }
    28.     char m[64];
    29.     fread(&m, sizeof(char), 64, f);
    30.     fclose(f);
    31.  
    32.     printf("%s\n", p);
    33.     printf("Cipher?(Y/n):");
    34.     fflush(stdout);
    35.     char r;
    36.     scanf("%c", &r);
    37.     do {
    38.         c = getchar();
    39.     } while (c != '\n' && c != EOF);
    40.     char ot = r;
    41.  
    42.     if (ot == 'Y') {
    43.         char s = 0;
    44.         for (int i = 0; i < 64; ++i) {
    45.             s ^= m[i];
    46.         }
    47.  
    48.         for (int i = 0; i < 63; ++i) {
    49.             m[i] ^= (m[i + 1] ^ s^r^i ^ ((0xf) << 4) ^ ((i % 2) << 7));
    50.             m[i] = f1(m[i]);
    51.         }
    52.         m[63] ^= s;
    53.  
    54.         FILE* f = fopen("out.txt", "wb");
    55.         fputc(s, f);
    56.         fwrite(m, sizeof(char), 64, f);
    57.         fclose(f);    
    58.     }
    59.  
    60.     return 0;
    61. }
    62. char f1(char a)
    63. {
    64.     char ss = 0xd;
    65.     static int t = 0;
    66.     int b = a1(rand()) % 0xffff;
    67.  
    68.     b <<= 4;
    69.     b ^= (k[(t++) % ss] >> 4);
    70.     b <<= 4;
    71.     b ^= (k[(t++) % ss]);
    72.  
    73.     a ^= (char)b;
    74.     return a;
    75. }
    76.  
    77. int a1(int a) {
    78.     if (a < 0)
    79.         return (-a);
    80.     else
    81.         return a;
    82. }

    Её суть в том, что она читает побайтно файл с текстом, а затем хорит его по определенному алгоритму и записывает в другой файл.
    В общем суть моего вопроса:
    помогите написать реверсирующую процедуру, т.е. чтобы подавая на вход зашифрованное сообщение получался исходный читаемый текст.
    Всю голову себе уже исколупал, 10 раз прошел по алгоритму, но все равно где-то я что-то упускаю (может сдвиг может еще что)
    И да, я знаю, что 2х xor дает исходный результат.

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

  2. По умолчанию

     
    Хотите избавиться от рекламы? Зарегистрируйтесь
  3. #2
    Moderator Куратор
    system architect
    Romeo is on a distinguished road Аватар для Romeo
    Регистрация
    02.03.2004
    Адрес
    Крым, Севастополь
    Возраст
    36
    Сообщений
    3,089
    Вес репутации
    21

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

    Выкладывай свою попытку. Будем разбираться, что не так.
    Entites should not be multiplied beyond necessity @ William Occam
    ---
    Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
    ---
    Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.

  4. #3
    dummy shwwawaw is on a distinguished road
    Регистрация
    02.04.2018
    Возраст
    20
    Сообщений
    3
    Вес репутации
    0

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

    Цитата Сообщение от Romeo Посмотреть сообщение
    Выкладывай свою попытку. Будем разбираться, что не так.
    Код cpp:
    1. #include <stdlib.h>
    2. #include <conio.h>
    3. #include <time.h>
    4. #include <stdio.h>
    5. #define k "jf1ay9238x0ax0"
    6. char f1(char a);
    7. int a1(int a);
    8.  
    9. int main()
    10. {
    11.     srand(time(0));
    12.  
    13.     printf("Enter path:");
    14.     fflush(stdout);
    15.     char p[64];
    16.     scanf("%s", p);
    17.     char c;
    18.     do {
    19.         c = getchar();
    20.     } while (c != '\n' && c != EOF);
    21.  
    22.     FILE* f = fopen(p, "rb");
    23.     if (f == NULL) {
    24.         printf("Error opening file");
    25.         getch();
    26.         exit(-3);
    27.     }
    28.     char m[64];
    29.     fread(&m, sizeof(char), 64, f);
    30.     fclose(f);
    31.  
    32.     printf("%s\n", p);
    33.     printf("Cipher?(Y/n):");
    34.     fflush(stdout);
    35.     char r;
    36.     scanf("%c", &r);
    37.     do {
    38.         c = getchar();
    39.     } while (c != '\n' && c != EOF);
    40.     char ot = r;
    41.  
    42.     if (ot == 'Y') {
    43.         char s = 0;
    44.         for (int i = 0; i < 64; ++i) {
    45.             s ^= m[i];
    46.         }
    47.  
    48.         for (int i = 0; i < 63; ++i) {
    49.             m[i] ^= (m[i + 1] ^ s^r^i ^ ((0xf) << 4) ^ ((i % 2) << 7));
    50.             m[i] = f1(m[i]);
    51.         }
    52.         m[63] ^= s;
    53.  
    54.         FILE* f = fopen("out.txt", "wb");
    55.         fputc(s, f);
    56.         fwrite(m, sizeof(char), 64, f);
    57.         fclose(f);    
    58.     }
    59.  
    60. /*
    61. Вот отсюда начинаем процесс
    62. В обратную сторону
    63. типа Xor x2 = text
    64. /*
    65.     printf("Enter path:");
    66.     fflush(stdout);
    67. /* Чтобы не париться
    68. переназначил переменный добавив
    69. к ним 0
    70. */
    71.     char p0[64];
    72.     scanf("%s", p0);
    73.     char c0;
    74.     do {
    75.         c0 = getchar();
    76.     } while (c0 != '\n' && c0 != EOF);
    77.  
    78.     FILE* f0 = fopen(p0, "rb");
    79.     if (f0 == NULL) {
    80.         printf("Error opening file");
    81.         getch();
    82.         exit(-3);
    83.     }
    84.     char m0[64];
    85.     fread(&m0, sizeof(char), 64, f0);
    86.     fclose(f0);
    87.  
    88.     printf("%s\n", p0);
    89.     printf("UNNCipher?(Y/n):");
    90.     fflush(stdout);
    91.     char r0;
    92.     scanf("%c", &r0);
    93.     do {
    94.         c0 = getchar();
    95.     } while (c0 != '\n' && c0 != EOF);
    96.     char ot0 = r0;
    97.  
    98.     if (ot0 == 'Y') {
    99. /* И вот здесь уже не понял
    100. В исходной проге S
    101. это ХОР всего текса побайтно
    102. и потом последний байт мы еще ксорим
    103. этим S
    104. т.е. перебрав 256 вариантов один из них будет
    105. верным ключем
    106. */
    107.         char s0;
    108.     scanf("%c", &s0);
    109. /* Этот цикл тогда вообще нужен?
    110. поидее - да
    111. */
    112. // берем последний байт, дексорим
    113.  
    114.  m0[63] ^= s0;
    115. // Потом цикл в обратную сторону
    116. for (int i = 62; i >= 0; --i) {
    117. // Вот здесь я так и не осознал
    118. // какое именно значение играет f1 функция
    119. m0[i] = f1(m0[i]);
    120. m0[i] ^= (m0[i + 1] ^ s0^r0^i ^ ((0xf) << 4) ^ ((i % 2) << 7));
    121.  
    122.         }
    123.  
    124.         for (int i = 63; i >=; ++i) {
    125.             s0 ^= m0[i];
    126.         }
    127.  
    128.         FILE* f = fopen("out.txt", "wb");
    129.         fputc(s, f);
    130.         fwrite(m, sizeof(char), 64, f);
    131.         fclose(f);    
    132.     }
    133.    
    134.     return 0;
    135. }
    136. char f1(char a)
    137. {
    138.     char ss = 0xd;
    139.     static int t = 0;
    140.     int b = a1(rand()) % 0xffff;
    141.  
    142.     b <<= 4;
    143.     b ^= (k[(t++) % ss] >> 4);
    144.     b <<= 4;
    145.     b ^= (k[(t++) % ss]);
    146.  
    147.     a ^= (char)b;
    148.     return a;
    149. }
    150.  
    151. int a1(int a) {
    152.     if (a < 0)
    153.         return (-a);
    154.     else
    155.         return a;
    156. }
    Вот примерно как-то так.
    Хз, я понимаю, что где-то косячу, но голова очень плохо усваивает подобные выкидоны
    поэтому обратился за помощью
    Последний раз редактировалось Romeo; 02.04.2018 в 13:07. Причина: [code=cpp][/code]

  5. #4
    Moderator Куратор
    system architect
    Romeo is on a distinguished road Аватар для Romeo
    Регистрация
    02.03.2004
    Адрес
    Крым, Севастополь
    Возраст
    36
    Сообщений
    3,089
    Вес репутации
    21

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

    Ты понимаешь, что зашифровать можно так, что потом не расшифруешь? Именно поэтому в криптографии разделяют алгоритмы на обратимые и необратимые. Если мы внимательно посмотрим в функцию f1, то увидим там использование rand(). Это приводит нас к однозначному выводу - данный алгоритм необратим, так как мы не знаем какие числа вернула функция rand() на этапе шифровки.
    Entites should not be multiplied beyond necessity @ William Occam
    ---
    Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
    ---
    Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.

  6. #5
    dummy shwwawaw is on a distinguished road
    Регистрация
    02.04.2018
    Возраст
    20
    Сообщений
    3
    Вес репутации
    0

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

    Цитата Сообщение от Romeo Посмотреть сообщение
    Ты понимаешь, что зашифровать можно так, что потом не расшифруешь? Именно поэтому в криптографии разделяют алгоритмы на обратимые и необратимые. Если мы внимательно посмотрим в функцию f1, то увидим там использование rand(). Это приводит нас к однозначному выводу - данный алгоритм необратим, так как мы не знаем какие числа вернула функция rand() на этапе шифровки.
    Она обратима
    Я тестил раз 100
    Она выдает один результат
    Там в функции еще приведение к char
    Короче это хм.. для отвлечения внимания видимо.

  7. #6
    Moderator Куратор
    system architect
    Romeo is on a distinguished road Аватар для Romeo
    Регистрация
    02.03.2004
    Адрес
    Крым, Севастополь
    Возраст
    36
    Сообщений
    3,089
    Вес репутации
    21

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

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

    Но даже если вдруг окажется, что это так, то этого не достаточно, чтобы преобразование было обратимым. Необходимое и достаточное условие обратимости - это взаимно однозначность преобразования. Судя по формулам, взаимно однозначности тут как раз нет.
    Entites should not be multiplied beyond necessity @ William Occam
    ---
    Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
    ---
    Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.

  8. #7
    Moderator Куратор
    system architect
    Absurd is on a distinguished road
    Регистрация
    26.02.2004
    Адрес
    Pietari, Venäjä
    Возраст
    38
    Сообщений
    1,213
    Вес репутации
    17

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

    Цитата Сообщение от Romeo Посмотреть сообщение
    Ты понимаешь, что зашифровать можно так, что потом не расшифруешь? Именно поэтому в криптографии разделяют алгоритмы на обратимые и необратимые. Если мы внимательно посмотрим в функцию f1, то увидим там использование rand(). Это приводит нас к однозначному выводу - данный алгоритм необратим, так как мы не знаем какие числа вернула функция rand() на этапе шифровки.
    Если seed один и тот же, то rand даст одинаковую цепочку значений.
    2B OR NOT(2B) = FF

  9. #8
    Moderator Куратор
    system architect
    Absurd is on a distinguished road
    Регистрация
    26.02.2004
    Адрес
    Pietari, Venäjä
    Возраст
    38
    Сообщений
    1,213
    Вес репутации
    17

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

    Цитата Сообщение от Absurd Посмотреть сообщение
    Если seed один и тот же, то rand даст одинаковую цепочку значений.
    А так, есть генераторы псевдослучайных чисел которые можно мотать в обратном порядке. Стандартный сишный вроде нельзя.
    2B OR NOT(2B) = FF

  10. #9
    Moderator Куратор
    system architect
    Romeo is on a distinguished road Аватар для Romeo
    Регистрация
    02.03.2004
    Адрес
    Крым, Севастополь
    Возраст
    36
    Сообщений
    3,089
    Вес репутации
    21

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

    Absurd, внимательней. Там seed сбрасывается через time, как положено
    Entites should not be multiplied beyond necessity @ William Occam
    ---
    Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
    ---
    Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.

  11. #10
    programmer Skwoogey is on a distinguished road
    Регистрация
    11.01.2016
    Сообщений
    63
    Вес репутации
    3

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

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

    Код cpp:
    1.     int b = a1(rand()) % 0xffff; //b = ...xxxxxxxx
    2.  
    3.     b <<= 4; //b = ...xxxx0000
    4.     b ^= (k[(t++) % ss] >> 4); //b = ...xxxxssss s - что-то что можно однозначно расчитать
    5.     b <<= 4; //b = ...ssss0000
    6.     b ^= (k[(t++) % ss]); //b = ...ssssssss
    7.  
    8.     a ^= (char)b; //используем только последние 8 бит

    Не помешало бы переменные и функции называть понятнее.

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

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

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

+ Ответить в теме

Похожие темы

  1. задача в Паскале.Цикл.помогите пжл!
    СУММА (значок)..i меняется от 1 до n...От выражения.. корень...под корнем (i в квадрате)+7...этот корень делится на ...25+ln(i).
    от selenka в разделе задачи на Паскале и Delphi
  2. Помогите создать цикл
    Всем привет:) В общем есть такой код: format pe gui entry start include 'win32a.inc' ...
    от SashOK в разделе Ассемблер
  3. Помогите написать прогу (цикл repeat-until, while-do)
    Помогите пожалуйста кто может, написать эту программу. Условие: Найти минимальное натуральное число N, которое можно изобразить в виде суммы кубов...
    от Juhn в разделе Решите мне задачку
  4. Помогите с задачкой (Цикл)
    Задача: Поле UNPAK содержит 01040705 в распакованном десятичном формате. Нужен цикл, который преобразует это содержимое в ASCII - формат, т.е....
    от Svet_lana в разделе Ассемблер

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения