Каков наилучший способ получить размер текста в Java (в байтах) - PullRequest
0 голосов
/ 25 февраля 2019

Примечание: я изо всех сил старался понять вашу проблему.Но извините, мой английский немного плохой.Потерпи!Если какая-то путаница комментирует меня.Спасибо за продвинутый

Я реализовал криптографический алгоритм в Java.Теперь я хочу измерить размер сообщения до и после шифрования в байтах.

Как получить размер текста в байтах ???

Например, если у меня естьпростой текст Hi! I am alphanumeric (8÷4=2)

Я старался изо всех сил, но не нашел лучших решений.

String temp = "Hi! I am alphanumeric (8÷4=2)"
temp.length() // this works because in ASCII every char takes one byte

// and in java every char in String takes two bytes so multiply by 2
temp.length() * 2

// also String.getBytes().length and getBytes("UTF-8").length
// returns same result

Но в моем случае после расшифровки сообщения символы становятся смесью ASCII иUnicode.

например, QÂʫPǒ!qÚy¦\dὥì£ὥ

Верхние методы возвращают length или length * 2

Но я хочу вычислить фактические байты (не в JVM).Например, char a в целом занимает один байт, а Unicode , например, занимает два байта.

Итак, как реализовать эту технику в Java.

Я хочу, чтобы кто-то вродеТехника, используемая на этом сайте http://bytesizematters.com/

Это дает мне 26 bytes для этого текста QÂʫPǒ!qÚy¦\dὥì£ὥ, хотя длина текста составляет 22.

Примечание: я хочу байты каквообще не в соответствии с JVM, как он хранит

1 Ответ

0 голосов
/ 25 февраля 2019

Имейте в виду: String для текста Unicode (возможность смешивать все виды скриптов), а char - это два байта UTF-16.

Это означает, что двоичные данные byte[] должнызнать его кодировку / кодировку и будет преобразован в строку.

byte[] b = ...
String s = ...
b = s.getBytes(StandardCharsets.UTF_8);
s = new String(b, StandardCharsets.UTF_8);

Без явной кодировки байтов используется платформа по умолчанию, которая выдаст непереносимый код.

UTF-8 разрешит весь текст, не только некоторые сценарии, но греческий, арабский, японский.

Однако, поскольку происходит преобразование, нетекстовые двоичные данные могут быть повреждены, не будет допустимым UTF-8,будет стоить вдвое больше памяти и будет медленнее из-за преобразования.

Поэтому избегайте String для двоичных данных любой ценой.

Чтобы ответить на ваш вопрос:

  • Вы можете уйти с помощью StandardCharsets.ISO_8859_1 - это однобайтовая кодировка.
  • String.getBytes(StandardCharsets.ISO_8859_1).length() будет тогда соответствовать String.length(), хотя строка может использовать двойную память как char2 байта.

Альтернативы для String:

  • byte[] сами по себе, Arrays предоставляют служебные функции, такие как arrayEquals.
  • ByteArrayInputStream, ByteArrayOutputStream
  • ByteBuffer можно завернуть byte[];может читать и писать короткие / int /...
  • Преобразовать строку byte[] в Base64 , используя Base64.getEncoder().encode(bytes).

Преобразование байта в некоторый символ

Цель состоит в том, чтобы преобразовать байт в видимый символ, отображаемый в текстовом поле графического интерфейса пользователя, где длина в символах одинаковакак число оригинальных байтов.

Например, шрифт Lucida Sans Unicode содержит от U + 2400 символов, представляющих управляющие символы ASCII.Для байтов с 8-м битом можно взять кириллицу, хотя может возникнуть путаница из-за сходства кириллицы е и латиницы e.

static char byte2char(byte b) {
    if (b < 0) { // -128 .. -1
        return (char)(0x400 - b);
    } else if (b < 32) {
        return (char)(0x2400 + b);
    } else if (b == 127) {
        return '\u25C1';
    } else {
        return (char) b;
    }
}

A char - кодировки UTF-16Unicode, но здесь также соответствует кодовой точке Unicode (int).

Байт подписан, следовательно, находится в диапазоне от -128 до 127.

...