Как исправить мой код шифрования / дешифрования, чтобы перейти в текстовый файл - PullRequest
0 голосов
/ 10 мая 2018

Каждый раз, когда я запускаю код, он говорит, что расшифрованный текстовый файл не может быть найден. Он работает без кода, который я не могу изменить (потому что мой учитель написал, что мы не можем), но с ним он отказывается работать. Мой учитель не поможет мне, и никто в моем классе не знает, как кодировать с помощью класса шифров. Я использовал класс PrintWriter и почти все остальное. Так что я не знаю, что делать. Кто-то, пожалуйста, помогите мне разобраться, как заставить это работать.

package Crypto;

import java.util.Scanner;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.FileWriter;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

public class Crypto {

 public static void main(String[] args) throws IOException {
  try {
   String key = "B1LLYB0B"; 

   FileInputStream One = new FileInputStream("CryptoPlaintext.txt");
   FileOutputStream Two = new FileOutputStream("CryptoCiphertext.txt");
   encrypt(key, One, Two);
   Two.flush();
   Two.close();


   FileInputStream One2 = new FileInputStream("CryptoCiphertext.txt");
   FileOutputStream Two2 = new FileOutputStream("CryptoDeciphered.txt");
   Two2.write(key.getBytes());
   Two2.close();
   decrypt(key, One2, Two2);
  } catch (Throwable e) {
   e.printStackTrace();
  }
 }

 public static void encrypt(String key, InputStream is, OutputStream os) throws Throwable {
  encryptOrDecrypt(key, Cipher.ENCRYPT_MODE, is, os);
 }

 public static void decrypt(String key, InputStream is, OutputStream os) throws Throwable {
  encryptOrDecrypt(key, Cipher.DECRYPT_MODE, is, os);
 }

 public static void encryptOrDecrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable {

  DESKeySpec dks = new DESKeySpec(key.getBytes());
  SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
  SecretKey desKey = skf.generateSecret(dks);
  Cipher cipher = Cipher.getInstance("DES"); 

  if (mode == Cipher.ENCRYPT_MODE) {
   cipher.init(Cipher.ENCRYPT_MODE, desKey);
   CipherInputStream cis = new CipherInputStream(is, cipher);
   doCopy(cis, os);
  } else if (mode == Cipher.DECRYPT_MODE) {
   cipher.init(Cipher.DECRYPT_MODE, desKey);
   CipherOutputStream cos = new CipherOutputStream(os, cipher);
   doCopy(is, cos);
  }
 }

 public static void doCopy(InputStream is, OutputStream os) throws IOException {
  byte[] bytes = new byte[64];
  int numBytes;
  while ((numBytes = is.read(bytes)) != -1) {
   os.write(bytes, 0, numBytes);
  }
  os.flush();
  os.close();
  is.close();





      // =============================== DO NOT MODIFY ANY CODE BELOW HERE ===============================

   // Compare the files

      System.out.println(compareFiles() ? "The files are identical!" : "The files are NOT identical.");

 }

 /**  
  *  Compares the Plaintext file with the Deciphered file.
  *
  *    @return  true if files match, false if they do not
  */

 public static boolean compareFiles() throws IOException
 {

       Scanner pt = new Scanner(new File("CryptoPlaintext.txt")); // Open the plaintext file
       Scanner dc = new Scanner(new File("CryptoDeciphered.txt"));  // Open the deciphered file

       // Read through the files and compare them record by record.
       // If any of the records do not match, the files are not identical.

       while(pt.hasNextLine() && dc.hasNextLine())
         if(!pt.nextLine().equals(dc.nextLine())) return false;

       // If we have any records left over, then the files are not identical.

       if(pt.hasNextLine() || dc.hasNextLine()) return false;

       // The files are identical.

       return true;

 }
}

1 Ответ

0 голосов
/ 10 мая 2018

Почему возникает ошибка: Вы вызываете метод compareFiles в своем методе копирования, который вызывается для копирования зашифрованного содержимого открытого текста в файл шифрованного текста. Когда этот вызов происходит, файл, содержащий расшифрованный зашифрованный текст, не существует, но требуется для метода compareFiles, что приводит к вашему исключению.

Как улучшить свой код:

  • вам не нужно заявление Two2.write(key.getBytes())
  • используйте оператор try-with-resource для автоматической очистки и закрытия потоков
  • стандартная библиотека предоставляет методы для копирования данных из пути в поток и наоборот. Взгляните на Files.copy (...) или Guava's ByteStreams.copy (...)
  • изменить ваши методы 'throws предложение, throws Throwable - это просто плохой дизайн, чтобы избавиться от правильной обработки исключений, если вы боретесь с InvalidKeyException, NoSuchAlgorithmException и т. Д., Ловите их, когда вы создаете свой шифр и например, отбросить IllegalArgumentException или пользовательское исключение

Вот пример того, как это реализовать:

public class Crypto
{
    public static void main(String[] args)
    {
        byte[] key = "B1LLYB0B".getBytes(StandardCharsets.UTF_8);

        Path plaintext = Paths.get("CryptoPlaintext.txt");
        Path ciphertext = plaintext.resolveSibling("CryptoCiphertext.txt");
        Path decrypted = ciphertext.resolveSibling("CryptoDeciphered.txt");

        try
        {
            // Encrypt plaintext.
            try (OutputStream os = encrypt(key, Files.newOutputStream(ciphertext)))
            {
                Files.copy(plaintext, os);
            }

            // Decrypt ciphertext.
            try (InputStream is = decrypt(key, Files.newInputStream(ciphertext)))
            {
                Files.copy(is, decrypted);
            }

            // TODO Compare plaintext and decrypted ciphertext.
        }
        catch (IOException e)
        {
            e.printStackTrace(); // TODO Handle exception properly.
        }
    }

    private static OutputStream encrypt(byte[] key, OutputStream os)
    {
        return new CipherOutputStream(os, getCipherInstance(key, Cipher.ENCRYPT_MODE));
    }

    private static InputStream decrypt(byte[] key, InputStream is)
    {
        return new CipherInputStream(is, getCipherInstance(key, Cipher.DECRYPT_MODE));
    }

    private static Cipher getCipherInstance(byte[] key, int mode)
    {
        // TODO Implement and return the desired cipher.
    }
}

Кстати: ваш учитель не закрывает свои сканеры в compareFiles(), что приводит к утечке ресурсов.

...