5

Я собираюсь использовать алгоритм для кодирования переменной длины, но очень длинный Строка, извлеченная из файла XML, тогда эти закодированные данные должны сохраняться в базе данных.Насколько эффективен алгоритм кодирования/декодирования класса BASE64 в Java?

Позже, когда я получаю второй файл, мне нужно получить зашифрованные данные из базы данных (ранее сохраненные), а затем декодировать их и проверить с новыми данными для дублирования.

Я попытался org.apache.commons.codec.binary.Base64 класс он имеет 2 метода:

  1. encodeBase64(Byte[] barray)
  2. decodeBase64(String str)

, который работает прекрасно, и решает мою проблему. Но он преобразует строку 55 char только в 6 строк символов.

Так что я задаюсь вопросом, есть ли случай, когда этот алгоритм кодирует 2 строки, которые очень большие и имеют только 1 несоответствие символов (например) в одинаковые закодированные байтовые массивы.

Я не знаю о классе Base64, но если кто-нибудь может мне помочь, это будет очень полезно.

Если вы можете предложить любой другой алгоритм, который делает большую строку длинной фиксированной длины и решает мою цель, я буду рад ее использовать.

Заранее спасибо.

+0

Любая правильная реализация base64 сделает строки больше не меньше. Вы пытаетесь сжать String? –

+0

да, на самом деле мне нужно немного алгоритма, чтобы сжать длинную строку в меньшую и сохранить в db, а затем раздуть ее, чтобы получить исходную строку. Я видел реализацию класса ZipOutputStream через Интернет, но я не пробовал. –

+0

Я думаю, что вы ищете хэш-функцию, такую ​​как [MD5] (http://en.wikipedia.org/wiki/MD5) (которая преобразует все входные данные в 128-байтовый вывод). Кодировка Base64, как правило, приводит к выводу, который составляет четыре трети размера ввода, поэтому он не приводит к выходу фиксированной длины вообще. –

ответ

12

Не очень эффективно.

Кроме того, использование классов sun.misc дает непереносимое приложение.

Заканчивать следующие сравнения производительности от MiGBase64:

enter image description here


Так интересно, если есть случай, когда их алгоритм кодирует 2 строк , которые очень большие и имеют только 1 несоответствие символов (например) в том же закодированных байтовых массивах.

Base64 не является алгоритмом хэширования, это кодирование и поэтому должно быть двунаправленным. Коллизии не могут быть разрешены по необходимости, иначе декодирование будет недетерминированным. Base64 предназначен для представления произвольных двоичных данных в строке ASCII. Кодирование строки Unicode в качестве Base64 часто будет . Увеличивает число с кодовыми точками, так как для набора символов Unicode требуется несколько байтов. Представление Base64 строки Unicode будет зависеть от используемой кодировки (UTF-8, UTF-16).Например:

Base64(UTF8("test")) => "dGVzdA==" 
Base64(UTF16("test")) => "/v8AdABlAHMAdA==" 

Solution 1

Использование без потерь сжатия

GZip(UTF8("test")) 

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

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

алгоритм решения 2

Используйте хеширования

SHA256(UTF8("test")) 

Здесь вы преобразовываете строку в набор фиксированных длин байтов с хеширующей функцией. Хеширование однонаправлено и по своей природе collisions can be possible. Однако, исходя из профиля и количества строк, которые вы ожидаете обработать, вы можете выбрать хеш-функцию, чтобы минимизировать вероятность столкновений.

Достоинства: Исправлены байт, необходимые для сохранения значения; байты, необходимая для хранения значения мало
Против: Коллизии возможно, нет возможности, чтобы восстановить исходную строку

+0

@johnstok Я понимаю вашу точку зрения, спасибо за информацию –

+0

@johnstok вы можете сказать мне способ эффективно сжать и распаковать строки? –

+0

@johnstok благодарит много :) –

1

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

В любом случае производительность выбранного вами алгоритма сжатия будет зависеть от характеристик входного текста. В отсутствие дополнительной информации сжатие DEFLATE (как используется входными потоками Zip, IIRC) является хорошим универсальным алгоритмом для начала и, по крайней мере, используется в качестве основы для сравнения. Однако для простоты реализации вы можете использовать класс Deflator, встроенный в JDK, который использует сжатие ZLib.

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

Эти и другие вопросы могут быть интересны:

+0

Во-первых, спасибо за ваше предложение. Я понимаю, что вы сказали. Базис64 здесь решает цель для меня, но то, что меня беспокоит, я могу полагать, что Base64 algo будет достаточно способен кодировать и декодировать эффективно для всех больших строк , Будет ли случай, когда алгоритм Base64 генерирует один и тот же вывод для больших строк, которые отличаются только одним символом или так? –

+0

** Выполняет ли ** base64 вашу цель? Я думал, что вы хотите сделать строки меньшими - base64 приведет к * увеличению * вывода. И он также не устанавливает ограничение на выходной размер - если входной сигнал составляет 3000 символов, кодированный вывод будет составлять 4000 символов, поэтому это может привести к сбою ваших требований для «эффективного кодирования для всех больших строк». Однако в ответ на ваш последний вопрос не будет никаких столкновений; base64 полностью двунаправленный. –

+0

да, извините, что изначально я думал, что класс Base64 сжимает вывод. Но позже выяснилось, что класс java.util.zip.Deflater и java.util.zip.Inflater - это то, что мне нужно, но снова застряло в выходе сжатой строки, это не в формате Unicode. Я пробовал перекомпоновать его на UTF8, но строковый литерал, отображаемый на моей консоли eclipse, не в формате UTF8. Мне нужно будет увидеть, могут ли эти данные сохраняться на моей базе данных Oracle. В любом случае спасибо за вашу помощь :) приветствия. –