Кодирование строковых значений с base64 - PullRequest
0 голосов
/ 04 марта 2020

, поэтому я работал над домашним заданием для своего класса CSC420. Профессор хотел, чтобы мы использовали код java для шифрования двух строковых значений, которые будет вводить пользователь. Я был в состоянии сделать, никакой реальной проблемы там; главная проблема в том, что образец вывода, который он нам дал, чтобы мы знали, если мы получили «правильный ответ», чем-то отличается от моего. Я приложил мой код ниже, мой вывод и его вывод; если бы кто-то мог сказать мне, что я делаю неправильно, это было бы очень признательно.

package Homework;

import static java.nio.charset.StandardCharsets.UTF_8; 
import java.util.Base64; 
import java.util.Base64.Encoder; 
import java.util.Scanner; 

public class HW4 { 
  public static String b64enc(String string) throws Exception { 

    Encoder encoder = Base64.getEncoder(); 
    byte[] data = string.getBytes(UTF_8); 
    String encodedString = encoder.encodeToString(data); 

return encodedString; 
} 

public static void main (String [] args) throws Exception { 

    Scanner scan1 = new Scanner(System.in);
      System.out.println("Please enter the first String: ");
      String string1 = scan1.nextLine();
      System.out.println("Please enter the second string: ");
      String string2= scan1.nextLine();
      scan1.close();  
      String encodedString = b64enc(string1 + string2);
      System.out.println(encodedString);
    }
} 

Text[![]] 1

enter image description here

Ответы [ 2 ]

2 голосов
/ 04 марта 2020

Я думаю, что теперь понимаю назначение.

Код должен кодировать одну строку сообщения , используя другую строку в качестве ключа. Base64 используется только для кодирования результата, поскольку он является двоичными данными и может (будет) содержать коды, которые нельзя распечатать - поэтому результат представляется в виде текста и, например, может быть отправлен по почте учителю.

Сначала отметим, что порядок строк не имеет значения, поэтому нет никакого реального различия между ключом и сообщением.

Далее мы можем декодировать результаты примера, например, используя linux command base64 (Я использовал GIT Bash, но для этого также доступны онлайн-сервисы). Я также передал результат в od (утилита шестнадцатеричного дампа, чтобы увидеть шестнадцатеричные значения):

$ echo "AAxMTE8=" | base64 -d | od -t x1 -c

, которая возвращает

0000000  00  0c  4c  4c  4f
         \0  \f   L   L   O

Обратите внимание, что это * Длина 1019 * байтов, то же самое, что и длина входной строки - поэтому мы можем предположить, что строки не объединяются, что приведет к изменению длины, но байты каждой строки каким-то образом объединяются. Кроме того, каждый символ использует один байт, поэтому кодировка, вероятно, равна UTF-8 или даже ASCII.

Далее мы видим, что результат заканчивается на "LLO", прописной версии конца самого длинного ввода "hello" - похоже, что позиция байтов не изменилась, только значения, объединенные какой-либо операцией. Давайте рассмотрим некоторые операции, которые можно использовать для объединения байтов:

  • Вычитание или деление : не будет работать, поскольку порядок ввода не имеет значения;
  • Добавление или умножение : не очень хорошо из-за возможного переполнения / недостаточного заполнения
  • Битовая И , NAND , ИЛИ или НОР : не сработает, потеря информации (например, x AND 0 всегда 0)
  • Битовая XOR (исключающее ИЛИ): (почти) идеально, легко зашифровать, легко расшифровать, порядок значения не имеет (но не очень сильный)

Позволяет проверить, что происходит с XOR :

input1: "hello" == [ 0x68, 0x65, 0x6c, 0x6c, 0x6f ] // using ASCII/UTF-8
input2: "hi"    == [ 0x68, 0x69 ]                   // "
result: "∅∅LLO" == [ 0x00, 0x0c, 0x4c, 0x4c, 0x4f ] // ∅ not printable

0x68 ^ 0x68 == 0x00  // correct!
0x65 ^ 0x69 == 0x0f  // "
0x6c ^  X   == 0x4c  // what is X?
0x6f ^  X   == 0x4f  // "

Теперь нам просто нужно посмотреть, что должно произойти с последними 3 байтами, один вход слишком короткий, то есть X. Нетрудно выяснить, что 0x6c ^ 0x20 == 0x4c и 0x6f ^ 0x20 == 0x4f, на самом деле A ^ X == B подразумевают, что A ^ B == X. Таким образом, мы заключаем, что строка меньшего размера должна быть заполнена 0x20 или символом пробела ' '.


Алгоритм должен быть примерно таким: сделать обе входные строки одинакового размера, добавив белую пробелы (' ') до меньшей строки. Преобразовать оба входа в байтовый массив. Объедините байты каждого массива, используя исключительное ИЛИ. Кодируйте результат, используя Base64.

2 голосов
/ 04 марта 2020

Тот факт, что программа вашего профессора имеет одинаковые контрольные значения для 'hihello' и 'hellohi', является особенным; очевидно, что только Base64-кодирование строки (которая не удаляет информацию; вы можете вернуться к оригиналу вместе с ней; в этом суть) подразумевает, что для 2 разных входов невозможно сгенерировать один и тот же вывод.

Я пришел к выводу, что вы не должны правильно прочитать инструкции. Вы ищете алгоритм, в котором ввод строк в другом порядке, тем не менее, дает одно и то же «закодированное значение». «объединить их, а затем base64 результат» не будет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...