Java-байт [] в строку и UTF-8 - PullRequest
1 голос
/ 03 декабря 2011

Я использую цепочку блоков шифров для школьной работы, и вопрос требует, чтобы метод взял String и вернул еще один String. Сначала я думал, что это странно, и переменные byte[] будут гораздо более адекватными, но метод все же реализован. В основном, вот код:

static public String encode(String message) {
   byte[] dataMessage = message.getBytes();
   ByteArrayOutputStream out = new ByteArrayOutputStream();

   byte last = (byte) (Math.random() * 256);
   byte cur;
   out.write(last);

   for (byte b : data) {
      cur = (byte) (b^last);
      System.out.println("Encode '" + (char) b + "' = " + b + "^" + last + " > " + cur );
      out.write( cur );
      last = cur;
   }

   System.out.println("**ENCODED BYTES = " + Arrays.toString(out.toByteArray()));
   System.out.println("**ENCODED STR   = " + Arrays.toString(out.toString().getBytes()));

   return out.toString();
}

Метод decode работает аналогично. Иногда метод выдаёт результаты вроде

Encode 'H' = 72^109 > 37
Encode 'e' = 101^37 > 64
Encode 'l' = 108^64 > 44
Encode 'l' = 108^44 > 64
Encode 'o' = 111^64 > 47
**ENCODED BYTES = [109, 37, 64, 44, 64, 47]
**ENCODED STR   = [109, 37, 64, 44, 64, 47]

Но иногда также будет плевать на вещи типа

Encode 'H' = 72^-63 > -119
Encode 'e' = 101^-119 > -20
Encode 'l' = 108^-20 > -128
Encode 'l' = 108^-128 > -20
Encode 'o' = 111^-20 > -125
**ENCODED BYTES = [-63, -119, -20, -128, -20, -125]
**ENCODED STR   = [-17, -65, -67, -17, -65, -67, -17, -65, -67, -17, -65, -67]

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

Ответы [ 2 ]

3 голосов
/ 03 декабря 2011

Вы не можете взять произвольную последовательность байтов и предположить, что это допустимая строка в кодировке UTF-8. Итак, я подозреваю, что метод toString, как документально подтверждено , , заменяет последовательности некорректного ввода и не отображаемых символов строкой замены по умолчанию для набора символов по умолчанию платформы .

Таким образом, вы не должны преобразовывать чисто двоичные данные в строку типа этой. Используйте некоторую кодировку, такую ​​как Hex или Base64, чтобы преобразовать ваши байты в печатаемую строку и наоборот.

Apache commons-codec имеет служебный класс Base64.

0 голосов
/ 03 декабря 2011

Это:

out.toString().getBytes()

не делает то, что вы ожидаете. Он принимает зашифрованные байты и интерпретирует эти байты, как если бы они были строкой в ​​кодировке UTF-8. Затем он преобразует символы в этой строке обратно в байты.

Вы не можете просто взять произвольные байты (в данном случае зашифрованные данные), а затем обработать их, как если бы это был текст в кодировке UTF-8.

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