2012-01-17 3 views
0

Я новичок в java, но я очень свободно владею C++ и C#, особенно C#. Я знаю, как сделать xor шифрование как на C#, так и на C++. Проблема заключается в том, что алгоритм, который я написал в Java для реализации шифрования xor, по-видимому, приводит к неправильным результатам. Результаты, как правило, представляют собой кучу пробелов, и я уверен, что это неправильно. Вот класс ниже:Моя реализация класса XOR шифрования XOR пошла не так

public final class Encrypter { 

    public static String EncryptString(String input, String key) 
    { 


     int length; 
     int index = 0, index2 = 0; 
     byte[] ibytes = input.getBytes(); 
     byte[] kbytes = key.getBytes(); 
     length = kbytes.length; 
     char[] output = new char[ibytes.length]; 
     for(byte b : ibytes) 
     { 
      if (index == length) 
      { 
       index = 0; 

      } 
      int val = (b^kbytes[index]); 
      output[index2] = (char)val; 
      index++; 
      index2++; 
     } 


     return new String(output); 
    } 
    public static String DecryptString(String input, String key) 
    { 
     int length; 
     int index = 0, index2 = 0; 
     byte[] ibytes = input.getBytes(); 
     byte[] kbytes = key.getBytes(); 
     length = kbytes.length; 
     char[] output = new char[ibytes.length]; 
     for(byte b : ibytes) 
     { 
      if (index == length) 
      { 
       index = 0; 

      } 
      int val = (b^kbytes[index]); 
      output[index2] = (char)val; 
      index++; 
      index2++; 
     } 


     return new String(output); 
    } 
} 
+2

не все символы могут быть напечатаны – gd1

+1

Зашифрованные данные должны обрабатываться как двоичные, его текст больше не является. –

+0

если вы зашифруете, то расшифруете текст, будет ли он правильно выводиться? –

ответ

2

Строки в Java является Unicode - и строка Unicode не являются общими для держателей байт, как ASCII строки могут быть.

Вы берете строку и преобразуете ее в байты без указания какой кодировки символов вы хотите, поэтому вы получаете кодировку по умолчанию для платформы - вероятно, US-ASCII, UTF-8 или одну из кодовых страниц Windows.

Затем вы выполняете арифметические/логические операции над этими байтами. (Я не смотрел на то, что вы здесь делаете, - вы говорите, что знаете алгоритм.)

Наконец, вы берете эти преобразованные байты и пытаетесь превратить их обратно в строку, то есть обратно персонажи. Опять же, вы не указали кодировку символов (но вы получите то же, что и вы, преобразовывая символы в байты, так что это нормально), но, что самое важное ...

Если ваша кодировка по умолчанию для платформы использует одиночный байт на символ (например, US-ASCII), то не все последовательности байтов, которые вы создадите, представляют собой действительные символы.

Таким образом, две части советов приходят от этого:

  1. Не использовать строки в качестве общих держателей для байтов
  2. Всегда указывать кодировку при преобразовании между байтами и символами.

В этом случае у вас может быть больше успеха, если вы специально укажете US-ASCII в качестве кодировки. EDIT: Последнее предложение неверно (см. Комментарии ниже). Обратитесь к пункту 1 выше! Используйте байты, а не символы, когда вам нужны байты.

+0

Чтобы расширить этот ответ, 'byte []' более уместен, чем 'String' для хранения байтов. Чтобы записать байты в stdout, используйте 'System.out.write (myByteArray)'. –

+1

Символы ASCII также предполагают, что 8-й бит равен 0, что, очевидно, неверно для двоичных данных. И множество расширенных страниц (OEM-страницы или что-то другое, что их называют). ASCII + верхние 128 символов с некоторыми другими знаками) также не обрабатывают весь диапазон. Afaik - единственная кодировка, которая МОЖЕТ обрабатывать весь 8-битный вход - это Windows-1252, и даже это указано, чтобы оставить несколько позиций пустым. Windows всегда всегда назначала некоторые контрольные знаки, чтобы они работали в целом. Но в целом: второе - последнее предложение - важная вещь: не используйте строки для хранения байтовых данных.если вам действительно нужно использовать base64 – Voo

+0

+1 для комментария Voo. ASCII не является владельцем байтов. ASCII определяет только 128 точек, а не 256. – TacticalCoder

0

Если вы используете строки не-ascii как ключи, вы получите довольно странные результаты. Байты в массиве kbytes будут отрицательными. Расширение знака означает, что значение val будет отрицательным. Затем приведение к символу будет производить символ в диапазоне FF80-FFFF.

Эти символы, конечно же, не подлежат печати, и в зависимости от того, что вы используете для проверки вывода, вы можете отобразить «поле» или некоторые другие сменные символы.

Смежные вопросы