@A_chlen_soveta

Программа для шифровки сообщений не работает. Почему?

Здравствуйте дорогие форумчане,

Решил я значит взяться за изучение ЯП JAVA. Сел и доучился до модулей (прошел массивы, типы данных, логические операторы, циклы, условные операторы, операторы сравнения). И как то услышал о такой штуке как XOR, после этого в голову пришла идея написать небольшой тренировочный проект под названием Day Coder.

Day Coder - это консольная программа для шифрования и расшифровки сообщений.
Принцип работы:
Программа берет ключ пользователя;
Далее вытаскивает с ПК сегодняшнее число;
Шифрует введенное пользователем сообщение сначала ключем пользователя, потом сегодняшним числом.
Таким образом сообщение зашифрованное 11 числа можно расшифровать только 11 числа любого месяца.

Т.к являюсь новичком в Java естественно возникли сложности и проблемы. Далее приведу код и в комментариях опишу ошибки. Заранее спасибо за помощь и ваши идеи по доработке программы.

1438090013_1072571484.jpg

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class MainClass {

    private static String personalKey = "";
    private static int personalKeyInt = 0;
    private static String massage = "";
    private static Scanner input = new Scanner(System.in);
/*Вот эти вот пре образования с датой тут ниже из за того что метод .getDay не работал у меня корректно */
    private static Date date = new Date();           
    private static SimpleDateFormat NowaDay = new SimpleDateFormat("dd");     
    private static String dayKeySt = NowaDay.format(date);          
    private static int dayKey = Integer.parseInt(dayKeySt);

    public static void main(String[] args) {
        String txtCommand = "";
        int n = 0;
        System.out.println("Добро пожаловать в программу Day Criptor!\nЭта программа предназначена для шифрования и дешиврования сообщений.");
        while (n != 1) {
            System.out.println("Введите нужную вам команду:\nstart - начать работу\nhelp - справка\nexit - выход");
            txtCommand = input.next();
            if (txtCommand.equals("start")) {
                int command = 3;
                PersonalKeyGiver();
                while (command != 0) {
                    System.out.println("Введите команду: ");
                    System.out.println("1 - Зашифровать сообщение\n2 - Расшифровать сообщение\n0 - Выход");
                    command = input.nextInt();
                    switch (command) {
                        case 0:
                            break;

                        case 1:
                            Coder();break;

                        case 2:
                            UnCoder();break;
                    }
                }
            }
            if (txtCommand.equals("help")) {
                FaQ();
            }
            if (txtCommand.equals("exit")) n++;
        }
    }


    public static void FaQ () {

        System.out.println("Добро пожаловать в программу Day Criptor!\nЭта программа предназначена для шифрования и дешифрования сообщений.\nВ программе используется уникальный метод шифрования, позволяющий расшифровать сообщение\nтолько в день его шифровки");
        System.out.println("Например: Вы защифровали сообщение 22 мая, чтобы расшифровать его нужно дождаться 22 числа любого месяца,\nесли попытаетесь расшифровать его 23 или 24 числа у вас это не выйдет.");
        System.out.println();
        System.out.println("ИНСТРУКЦИЯ ПО ИСПОЛЬЗОВАНИЮ ПРОГРАММЫ\nЗапустите программу, введите 'start' чтобы начать шифрование или дешифровку сообщения\nДалее вам предложат ввести 4-х значный ключ.");
        System.out.println("Если вы шифруете сообщение то придумайте надежный ключ(Пункт 1). \nЕсли дешифруете введите ключ которым сообщение было зашифровано(Пункт 2).\nПосле нам непосредственно предложат вариант шифровать или расшифровывать\n\nПункт 1:");
        System.out.println("ВНИМАНИЕ ДАЛЬНЕЙШАЯ ИНСТРУКЦИЯ ДЛЯ ТЕХ КТО ХОЧЕТ ЗАШИФРОВАТЬ СООБЩЕНИЕ!");
        System.out.println("После того как вы выбрали вариант с шифровкой вам предложат ввести ваше сообщение. Введите сообщение в одну строку в конце нажмите 'Enter'.\nНа выходе вы получите свой ключ, день использовавшийся для шифровки и само сообщение в зашифрованном виде");
        System.out.println();
        System.out.println("Пункт 2:\nВНИМАНИЕ ДАЛЬНЕЙШАЯ ИНСТРУКЦИЯ ДЛЯ ТЕХ КТО ХОЧЕТ ДЕШИФРОВАТЬ СООБЩЕНИЕ!");
        System.out.println("После того как вы выбрали вариант с дешифровкой вам предложат ввести ваше сообщение. Введите сообщение в одну строку в конце нажмите 'Enter'.\nНа выходе вы получите свой ключ, день использовавшийся для дешифровки и само сообщение в дешифрованном виде");
        System.out.println();
    }


    public static void PersonalKeyGiver () {

        for ( int i = 0;(i != 4); ) {
            System.out.print("Введите свой 4-х значный ключ(Запомните его это key1): ");
            personalKey = input.next();
            i = personalKey.length();

        }
/*эти преобразования тут из-за того что на моем ПК не отображались корректно символы Юникода после 906 символа. Если есть какие-то иные методы решения данной проблемы пожалуйста подскажите*/
        personalKeyInt = Integer.parseInt(personalKey);     
        while (personalKeyInt > 906) {          
            personalKeyInt = personalKeyInt - 906;     
        }      
    }
    public static void Coder () {
        System.out.println("Введите ваше сообщение: ");
/*Вот тут и вся проблема. nextLine просто перескакивает на след.команду как будто я нажал 'Enter'*/
        massage = input.nextLine();    
        int msgL = massage.length();     
        char[] newMassage = new char[msgL];
        for (int x = 0; x < msgL; x++) {
            newMassage[x] = (char)(massage.charAt(x) ^ personalKeyInt);
            newMassage[x] = (char)(newMassage[x] ^ dayKey);
        }
        System.out.print("Ваш ключ (key1) : ");
        System.out.println(personalKey);
        System.out.print("Ключевой день (key2) : ");
        System.out.println(dayKey);
        System.out.println("Ваше зашифрованное сообщение:");
        System.out.println(newMassage);
    }
    public static void UnCoder() {
        System.out.println("Введите сообщение для дешифровки: ");
        massage = input.nextLine();
        int msgLen = massage.length();
        char[] uncriptMassage = new char[msgLen];
        for (int x = 0; x < msgLen; x++) {
            uncriptMassage[x] = (char)(massage.charAt(x) ^ dayKey);
            uncriptMassage[x] = (char)(uncriptMassage[x] ^ personalKeyInt);
        }
        System.out.print("Ваш ключ (key1) : ");
        System.out.println(personalKeyInt);
        System.out.print("Ключевой день (key2) : ");
        System.out.println(dayKey);
        System.out.println("Ваше расшифрованное сообщение сообщение:");
        System.out.println(uncriptMassage);
    }

}

P.S Просьба не кидать помидорками
  • Вопрос задан
  • 262 просмотра
Решения вопроса 1
@mr_molyar
Java back-end developer
Если не вдаваясь в подробности, то по факту, он читает линию с первого ввода, на сколько я сам понимаю, проблема в том, что нажимая на enter в первом вводе, в твоём случае это ввод числа, ты автоматом, создаёшь пустую строку, в случае с next или nextInt, сканер не видит данных, которые может сканировать и предлагает ввести новые, но для nextLine, нет разницы, что ты введёшь. Короче, либо создавай новый сканер в методе Code, либо принимай дважды input.nextLine, можешь ещё что нибудь придумать с input.hasNext
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
mayton2019
@mayton2019 Куратор тега Java
Bigdata Engineer
Лови первую помидорку!

Нет смысла делать операции XOR над char типом данных.
newMassage[x] = (char)(newMassage[x] ^ dayKey);
В криптографии если ты решил серъезно играть - то надо весь открытый текст перевести в byte array
(здесь как раз появляется понятие кодовая страница) и потом применить XOR к этому байтовому массиву.
Для печати на экране байт-масив переводят либо в binhex, либо в base64.

Для дешифрования - соотв. надо сделать обратный цикл. Из binhex в байтовый массив. Потом из него XOR и потом - национальная кодовая страница.
Ответ написан
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Таким образом сообщение зашифрованное 11 числа можно расшифровать только 11 числа любого месяца.
А мужики-то и не знают!))

Сделайте наоборот: вначале маскирование по числу месяца вместе с ключом, а потом - шифруйте получившийся набор только ключом: защита - будет куда лучше!
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы