Java 8 запомнится тем, что привнесла в Java лямбда-выражения, потоки, новую модель даты/времени и движок Nashorn JavaScript. Некоторые до сих пор помнят Java 8, поскольку она представила различные небольшие, но полезные функции, такие как API Base64. Что такое Base64 и как использовать этот API? Эта статья отвечает на эти вопросы.
Что такое Base64?
существуетRFC 1421Base64 был впервые описан (но не назван) в: Улучшения конфиденциальности для электронной почты в Интернете: часть первая: процесс шифрования и аутентификации сообщений. Позже это былоRFC 2045Официально отображается как Base64: Многоцелевые расширения почты Интернета (MIME), часть 1: формат тела сообщения Интернета, затем вRFC 4648: кодирование данных Base16, Base32 и Base64.пересмотреть.
Base64 используется для предотвращения изменения данных при передаче информационными системами (такими как электронная почта), которые могут не быть 8-битными (они могут быть 8-битными значениями). Например, вы прикрепляете изображение к сообщению электронной почты и хотите, чтобы изображение дошло до другого конца без искаженных символов. Ваше почтовое программное обеспечение Base64 кодирует изображение и вставляет эквивалентный текст в сообщение, как показано на изображении ниже:
Content-Disposition: inline;
filename=IMG_0006.JPG
Content-Transfer-Encoding: base64
/9j/4R/+RXhpZgAATU0AKgAAAAgACgEPAAIAAAAGAAAAhgEQAAIAAAAKAAAAjAESAAMAAAABAAYA
AAEaAAUAAAABAAAAlgEbAAUAAAABAAAAngEoAAMAAAABAAIAAAExAAIAAAAHAAAApgEyAAIAAAAU
AAAArgITAAMAAAABAAEAAIdpAAQAAAABAAAAwgAABCRBcHBsZQBpUGhvbmUgNnMAAAAASAAAAAEA
...
NOMbnDUk2bGh26x2yiJcsoBIrvtPe3muBbTRGMdeufmH+Nct4chUXpwSPk/qK9GtJRMWWVFbZ0JH
I4rf2dkZSbOjt7hhEzwcujA4I7Gust75pYVwAPpXn+kzNLOVYD7xFegWEKPkHsM/pU1F0NKbNS32
o24sSCOlaaFYLUhjky4x9PSsKL5bJsdWkAz3xirH2dZLy1DM2C44zx1FZqL2PTXY/9k=
На иллюстрации видно, что это закодированное изображение начинается с/
начало и конец=
. существует...
Указывает, что текст не отображается. Обратите внимание, что вся кодировка для этого или любого другого примера примерно на 33% больше, чем исходные двоичные данные.
Программное обеспечение электронной почты получателя декодирует закодированное текстовое изображение с помощью Base64, чтобы восстановить исходное двоичное изображение. В этом примере изображение будет отображаться вместе с остальной частью сообщения.
Кодирование и декодирование Base64
Base64 опирается на простые алгоритмы кодирования и декодирования. Они используют 65-символьное подмножество US-ASCII, где каждый из первых 64 символов соответствует эквивалентной 6-битной двоичной последовательности. Вот алфавит:
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
65 символов (=
) используется для заполнения текста в кодировке Base64 до целочисленного размера, как описано ниже.
Алгоритм кодирования получает входной поток из 8-битных байтов. Предполагается, что поток упорядочивается самым старшим битом первым: первый бит — это старший бит в первом байте, восьмой бит — это младший бит в этом байте и так далее.
Слева направо байты организованы в 24-битные группы. Каждая группа обрабатывается как четыре конкатенированные группы по 6 битов. Каждая 6-битная группа индексируется как массив из 64 печатных символов; выведите полученные символы.
Когда в конце закодированных данных доступно менее 24 бит, добавляются нулевые биты (справа), чтобы сформировать целое число 6-битных групп. Затем вы можете вывести один или два=
символы заполнения. Следует рассмотреть две ситуации:
- Один оставшийся байт: добавьте четыре нулевых бита к этому байту, чтобы сформировать две 6-битные группы. Каждая группа индексирует массив и выводит полученные символы. После этих двух символов выведите два
=
символы заполнения. - Оставшиеся два байта: два нулевых бита добавляются ко второму байту, образуя три 6-битных группы. Каждая группа индексирует массив и выводит полученные символы. После этих трех символов вывод
=
символы заполнения.
Давайте рассмотрим три примера, чтобы понять, как работает алгоритм кодирования. Во-первых, допустим, мы хотим закодировать@!*
:
Source ASCII bit sequences with prepended 0 bits to form 8-bit bytes:
@ ! *
01000000 00100001 00101010
Dividing this 24-bit group into four 6-bit groups yields the following:
010000 | 000010 | 000100 | 101010
These bit patterns equate to the following indexes:
16 2 4 42
Indexing into the Base64 alphabet shown earlier yields the following encoding:
QCEq
Мы продолжим сокращать входную последовательность до@!
:
Source ASCII bit sequences with prepended 0 bits to form 8-bit bytes:
@ !
01000000 00100001
Two zero bits are appended to make three 6-bit groups:
010000 | 000010 | 000100
These bit patterns equate to the following indexes:
16 2 4
Indexing into the Base64 alphabet shown earlier yields the following encoding:
QCE
An = pad character is output, yielding the following final encoding:
QCE=
Последний пример сокращает входную последовательность до@
:
Source ASCII bit sequence with prepended 0 bits to form 8-bit byte:
@
01000000
Four zero bits are appended to make two 6-bit groups:
010000 | 000000
These bit patterns equate to the following indexes:
16 0
Indexing into the Base64 alphabet shown earlier yields the following encoding:
QA
Two = pad characters are output, yielding the following final encoding:
QA==
Алгоритм декодирования является обратным алгоритмом кодирования. Однако, когда не обнаружено Base64 алфавит символ или символы заполнены неправильно, вы можете предпринять бесплатные подходящие меры.
Вариант Base64
Было разработано несколько вариантов Base64. Некоторые варианты требуют, чтобы закодированный выходной поток был разделен на несколько строк фиксированной длины, каждая строка не превышала определенного предела длины и (за исключением последней строки) отделялась от следующей строки разделителем строк (возврат каретки).\r
с последующей новой строкой\n
). Я описываю три варианта, поддерживаемые Base64 API Java 8. Посмотреть ВикипедиюBase64запись для полного списка вариантов.
Basic
RFC 4648 описывает метод, называемый
Вариант базового64. Этот вариант использует алфавит Base64, показанный в таблице 1 RFC 4648 и RFC 2045 (и ранее показан в этой статье) для кодирования и декодирования. Кодер требует кодированного выходного потока в виде одной строки; нет разделителя линии вывода. Декодер отвергает кодировки, содержащие символы вне алфавита Base64. Обратите внимание, что эти и другие положения могут быть переопределены.
MIME
RFC 2045 описывает метод под названием
Вариант Base64 файла . В этом варианте для кодирования и декодирования используется алфавит Base64, представленный в таблице 1 RFC 2045. Закодированный выходной поток организован в строки не более 76 символов, каждая строка (кроме последней) отделяется от следующей строки разделителем строк. Все разделители строк или другие символы, не встречающиеся в алфавите Base64, при декодировании игнорируются.
URL and Filename Safe
RFC 4648 описывает метод, называемый
Вариант Base64 файла . В этом варианте для кодирования и декодирования используется алфавит Base64, представленный в таблице 2 RFC 4648. Алфавит такой же, как показано ранее, только-
заменять+
и_
заменять/
. Не выводить разделители строк. Декодер отклоняет кодировки, содержащие символы вне алфавита Base64.
Кодировка Base64 полезна в контексте длинных двоичных данных и HTTP-запросов GET. Идея состоит в том, чтобы закодировать эти данные, а затем добавить их к URL-адресу HTTP GET. При использовании варианта Basic или MIME любые в закодированных данных+
или/
символы должны быть закодированы URL как шестнадцатеричная последовательность (+
стать%2B
и/
стать%2F
). Сгенерированная строка URL займет больше времени. Заменять+
такой же-
и/
такой же_
, безопасность URL-адресов и имен файлов устраняет необходимость в кодировщиках/декодировщиках URL-адресов (и влиянии длины их закодированных значений). Кроме того, этот вариант полезен, когда для имен файлов используются закодированные данные, поскольку имена файлов Unix и Windows не могут содержать/
.
Использование Java Base64 API
Java 8 представляет API Base64, в том числеjava.util.Base64
Классы и их вложенностьstatic
своего родаEncoder
иDecoder
.Base64
Есть несколько способов получить кодеры и декодерыstatic
метод:
-
Base64.Encoder getEncoder()
: Возвращает кодировщик для базового варианта. -
Base64.Decoder getDecoder()
: возвращает декодер для варианта Basic. -
Base64.Encoder getMimeEncoder()
: возвращает кодировщик для варианта MIME. -
Base64.Encoder getMimeEncoder(int lineLength, byte[] lineSeparator)
: возвращается с заданнымlineLength
Модифицированный MIME-вариант кодировщика (округленный до ближайшего кратного 4 - вывод вlineLength
lineSeparator. когдаlineSeparator
При использовании любой из буквенных символов Base64, перечисленные в таблице 1 RFC 2045, он бросаетjava.lang.IllegalArgumentException
.getMimeEncoder()
Кодировщик RFC 2045, возвращаемый методом, является довольно строгим. Например, этот кодировщик создает закодированный текст с фиксированной длиной строки 76 символов (кроме последней строки). Если вы хотите, чтобы ваш кодировщик поддерживал RFC 1421, в котором указана фиксированная длина строки в 64 символа, вам необходимо использоватьgetMimeEncoder(int lineLength, byte[] lineSeparator)
. -
Base64.Decoder getMimeDecoder()
: возвращает декодер для варианта MIME. -
Base64.Encoder getUrlEncoder()
: возвращает кодировщик для вариантов URL и Filename Safe. -
Base64.Decoder getUrlDecoder()
: возвращает декодер для вариантов URL и Filename Safe.
Base64.Encoder
Для кодирования последовательностей байтов предлагается несколько потокобезопасных методов экземпляра. Передача нулевой ссылки одному из следующих методов приводит кjava.lang.NullPointerException
:
-
byte[] encode(byte[] src)
:будетsrc
Все байты кодируются во вновь выделенный массив байтов, и возвращается результат. -
int encode(byte[] src, byte[] dst)
:кодированиеsrc
все байты вdst
(开始于偏移0)。 еслиdst
не хватило сохранить кодировку, скинутьIllegalArgumentException
. В противном случае вернуться к записиdst
количество байт. -
ByteBuffer encode(ByteBuffer buffer)
:будетbuffer
Все оставшиеся байты кодируются во вновь выделенномjava.nio.ByteBuffer
в объекте. После возвращения,buffer
Позиция будет обновлена до его предела; его предел не изменится. Положение выходного буфера возвращается на ноль, что ограничит количество байтов результата кодирования. -
String encodeToString(byte[] src)
:будетsrc
Все байты кодируются как строка, и эта строка возвращается. Вызов этого метода эквивалентен выполнениюnew String(encode(src), StandardCharsets.ISO_8859_1)
. -
Base64.Encoder withoutPadding()
: возвращает кодировщик, который кодирует эквивалент этого кодировщика, но без добавления каких-либо символов заполнения в конец закодированных данных байтов. -
OutputStream wrap(OutputStream os)
: Оборачивает выходной поток для кодирования байтовых данных. Рекомендуется закрыть возвращаемый поток вывода сразу после использования, в течение которого он сбрасывает все возможные оставшиеся байты в базовый поток вывода. Закрытие возвращенного выходного потока закроет базовый выходной поток.
Base64.Decoder
Предлагается несколько потокобезопасных методов экземпляра для декодирования последовательностей байтов. Передача нулевой ссылки одному из следующих методов приводит кNullPointerException
:
-
byte[] decode(byte[] src)
:будетsrc
Все байты декодируются во вновь выделенный массив байтов и возвращаются. Брошен, когда Base64 недействителенIllegalArgumentException
. -
int decode(byte[] src, byte[] dst)
: декодированиеsrc
все байты вdst
(начиная со смещения 0). еслиdst
Недостаточно для сохранения декодирования или выдает, когда Base64 недействителенIllegalArgumentException
. В противном случае вернуться к записиdst
количество байт. -
byte[] decode(String src)
:будетsrc
Все байты декодируются в новый выделенный массив байтов, и этот массив байтов возвращается. Вызов этого метода эквивалентен вызовуdecode(src.getBytes(StandardCharsets.ISO_8859_1))
. Брошен, когда Base64 недействителенIllegalArgumentException
. -
ByteBuffer decode(ByteBuffer buffer)
:будетbuffer
Все байты декодируются как вновь выделенныеjava.nio.ByteBuffer
объект. После возвращения,buffer
Его позиция будет обновлена до своего предела, его предел не изменится. Позиция возвращаемого выходного буфера будет равна нулю, а его пределом будет количество произведенных декодированных байтов. Брошен, когда Base64 недействителенIllegalArgumentException
. при этих обстоятельствах,buffer
Местоположение не будет обновляться. -
InputStream wrap(InputStream is)
: Оборачивает входной поток для декодирования байтовых данных. Когда ввод Base64 недействителен,is
объектread()
броски методаjava.io.IOException
. Закрытие возвращенного выходного потока закроет базовый выходной поток.
Привет Base64
Java Base64 API прост в использовании. Рассмотрим программу в стиле «Hello, World», которая кодирует Base64 с помощью базового кодировщика, а затем Base64 декодирует закодированный текст с помощью базового декодера. В листинге 1 показан исходный код.
Листинг 1. HelloBase64.java
import java.util.Base64;
public class HelloBase64
{
public static void main(String[] args)
{
String msg = "Hello, Base64!";
Base64.Encoder enc = Base64.getEncoder();
byte[] encbytes = enc.encode(msg.getBytes());
for (int i = 0; i < encbytes.length; i++)
{
System.out.printf("%c", (char) encbytes[i]);
if (i != 0 && i % 4 == 0)
System.out.print(' ');
}
System.out.println();
Base64.Decoder dec = Base64.getDecoder();
byte[] decbytes = dec.decode(encbytes);
System.out.println(new String(decbytes));
}
}
Скомпилируйте листинг 1 следующим образом:
javac HelloBase64.java
Запустите полученное приложение следующим образом:
java HelloBase64
Вы должны наблюдать следующий вывод:
SGVsb G8sI EJhc 2U2N CE=
Hello, Base64!
Кодирование и декодирование файлов
Base64 закодированный файл более полезный. Я создал второе приложение, которое демонстрирует полезность этой и дополнительной API Base64. Листинг 2 показывает исходный код для приложения.
Листинг 2. FileEncDec.java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Base64;
public class FileEncDec
{
public static void main(String[] args)
{
if (args.length != 1)
{
System.err.println("usage: java FileEncDec filename");
return;
}
try (FileInputStream fis = new FileInputStream(args[0]))
{
Base64.Encoder enc1 = Base64.getEncoder();
Base64.Encoder enc2 = Base64.getMimeEncoder();
Base64.Encoder enc3 = Base64.getUrlEncoder();
OutputStream os1 = enc1.wrap(new FileOutputStream(args[0] + "1.enc"));
OutputStream os2 = enc2.wrap(new FileOutputStream(args[0] + "2.enc"));
OutputStream os3 = enc3.wrap(new FileOutputStream(args[0] + "3.enc"));
int _byte;
while ((_byte = fis.read()) != -1)
{
os1.write(_byte);
os2.write(_byte);
os3.write(_byte);
}
os1.close();
os2.close();
os3.close();
}
catch (IOException ioe)
{
System.err.printf("I/O error: %s%n", ioe.getMessage());
}
try (FileOutputStream fos1 = new FileOutputStream("1" + args[0]);
FileOutputStream fos2 = new FileOutputStream("2" + args[0]);
FileOutputStream fos3 = new FileOutputStream("3" + args[0]))
{
Base64.Decoder dec1 = Base64.getDecoder();
Base64.Decoder dec2 = Base64.getMimeDecoder();
Base64.Decoder dec3 = Base64.getUrlDecoder();
InputStream is1 = dec1.wrap(new FileInputStream(args[0] + "1.enc"));
InputStream is2 = dec2.wrap(new FileInputStream(args[0] + "2.enc"));
InputStream is3 = dec3.wrap(new FileInputStream(args[0] + "3.enc"));
int _byte;
while ((_byte = is1.read()) != -1)
fos1.write(_byte);
while ((_byte = is2.read()) != -1)
fos2.write(_byte);
while ((_byte = is3.read()) != -1)
fos3.write(_byte);
is1.close();
is2.close();
is3.close();
}
catch (IOException ioe)
{
System.err.printf("I/O error: %s%n", ioe.getMessage());
}
}
}
ДолженFileEncDec
Приложение ожидает файл в качестве имени своего потерянного аргумента командной строки. Он продолжает открывать этот файл и читать его содержимое. Каждый прочитанный байт записывается в другой файл через другой кодировщик и обернутый поток вывода. После этого эти файлы открываются и считываются с помощью различных декодеров и обернутых входных потоков. Результаты сохраняются в трех отдельных файлах.
Скомпилируйте листинг 2 следующим образом:
javac FileEncDec.java
Запустите получившееся приложение следующим образом (при условии, что файл с именем JPEGimage.jpg
- см. архив кода к посту):
java FileEncDec image.jpg
Вы должны наблюдать в текущем каталогеimage.jpg1.enc
,image.jpg2.enc
иimage.jpg3.enc
документ.
image.jpg1.enc
Сохраните базовую кодировку в одной длинной строке. Ниже приведен префикс вывода, разделенный на две строки для удобства чтения (...
Содержание представления последовательности не показано):
/9j/4AAQSkZJRgABAQEASABIAAD/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAEAAAAAAAD/
4QM6aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+...
image.jpg2.enc
Сохраните кодировку MIME в нескольких строках:
/9j/4AAQSkZJRgABAQEASABIAAD/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAEAAAAAAAD/
4QM6aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9
Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pg0KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpu
czptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEw
LzAyLzEyLTE3OjMyOjAwICAgICAgICAiPg0KCTxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3
dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+DQoJCTxyZGY6RGVzY3JpcHRpb24g
cmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1s
bnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJo
dHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRv
clRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzUgV2luZG93cyIgeG1wTU06SW5zdGFuY2VJRD0ieG1w
LmlpZDoyMzlCQTU3RjY3RDMxMUUzODg3OEFGOTg0RUUzMkVBOSIgeG1wTU06RG9jdW1lbnRJRD0i
eG1wLmRpZDoyMzlCQTU4MDY3RDMxMUUzODg3OEFGOTg0RUUzMkVBOSI+DQoJCQk8eG1wTU06RGVy
aXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoyMzlCQTU3RDY3RDMxMUUzODg3OEFG
OTg0RUUzMkVBOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyMzlCQTU3RTY3RDMxMUUzODg3
OEFGOTg0RUUzMkVBOSIvPg0KCQk8L3JkZjpEZXNjcmlwdGlvbj4NCgk8L3JkZjpSREY+DQo8L3g6
eG1wbWV0YT4NCjw/eHBhY2tldCBlbmQ9J3cnPz7/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYE
BAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYM
CAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAAR
CAAeADADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgED
AwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRol
JicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWW
l5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3
+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3
AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5
OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaan
qKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIR
AxEAPwD4y1DwrZ3epxppsxS3cfeu+HUDO5yqAnbweEDkY6k11fw4+GWqeI9JhSVdBt9Ljma6Ek9r
FctNIiqTEzxgybSDGChYL+9XALMM/JegyRfEgSTb9bsWRDKRNEbhlD7WXaU5IYuMMABkkkdSOh8R
RSJcxx3etaha2cajCTJ5URXLFXljPzu3mbThlYZ6Z5A7KvFNFv2cZpPzvf8AJK/3k0chqW9pKLa8
rW/Vn3t8QvFPjb4x67pOm+NNQ0O60nTLb93YWV9Nplpdg4HkzSAFlCRFkHUgBc8FiPBde8IyWuma
pfXnhW6sYdPVXeaK6WO0hSRhHENzZ8xtxUfKxZuSc5BHz78NfjD4m8D+L9S1nSbfxprV5q0TLqd3
aRzNLewuypyXyZkO9sIE2rsU4GMjd+HXizVPhemq3Xh61+L1zHrbLpl3LcaVt8uzYoGkBKs8bqD8
skfzFN4Kxh+eT/Wilhnytp7bJ2v1Wj0b8/yR1f2DOurxut92vlvul5H0xofxB8Eaf8HZobj4c6dp
uqarp8unwa3DK97I43qXxHK5SKbB/wBafmCnCAKeOB8Pado91dTxpazpBJC6nMMV3M4xyFZ02xnq
fMVdy449R4V8X/E0PhT4kRtZ2Xju+tlhMUE0OoJHLDKjgMojKbGiMSbxlVGSoyONvK3H7Rnia90O
2l0OG8WeztVW5kJE7pN5SLvXAHLSuxbhjwNuxQRV4XiqlVp+0hCXvaq7Xyvdt+W2+yM8Vw/UpT5J
zj7ujsn+iS8/zZ+h91qGi3t7Lpsmi3CR+SLi3+y3kkIjTgZYBDhlG7bxkZPLFhWh47+EmgzeDdQ8
UeEdYbTdPUL9p0xtUuJyJtuxWEsbxnBOThwuArAsVznFstCaLxjpuk7bdYLi5+ybQhYIpcxEg8cj
jHsPUkn16Pwf/wAIHqL2d5cR6ppdx+7Wze2CQuihTyqsNh28gglg3RgBz+FYOpDBzi5RUodU0ndd
d1v1Wq1P0DETnibtVGpdNWrfd/wT520DRfEV1eyWt3cXek/2ZCF3Tt9str8RxKCVZozI0rKFwC6Y
L84GBUC+GfE2sQ6nNc3Gl6T/AGezSodT0mOX7RIxxGEEbqFkxuHqSVXJJBEn7YNvJ8Dvit9ttbi+
uNH1WITC3FwI7i33gSbFYJt2j7v3eRk4ycjwo/F6bTPOjT7bI0gJLtPy+75lDDoccE+9fquG4Syv
F044mnTSUkmrJrR+V/0PjqnE2OoN0ZTbs3e7PbdHbXtGvlSbS/Ccmm3Nq7/aLN73TWluFXhgD5q5
BZeuMbQAVANN8feJYfBuoLqFj4L1jUrW1t45ZpV8SIJbNiqyNuD5Dqm6TDA/KcggEYrF8M/FTQ9c
+HurfZLfV7jVNJ0sag320oIBH5yqyoUbcrfMT6HnIGa53Qvi9b+WGkspp47hWQo7jKj2YflyDkVn
/qPgJXlFyT23dvuTX5ov/WrGxsna3or/AHtM/9k=
image.jpg3.enc
Храните URL-адреса и имена файлов, безопасно закодированные в одной длинной строке. Ниже приведен префикс вывода, разделенный на две строки для удобства чтения:
_9j_4AAQSkZJRgABAQEASABIAAD_4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAEAAAAAAAD_
4QM6aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu-...
image.jpg1.enc
иimage.jpg3.enc
Разница между каждым/
заменены на_
и каждый+
заменены на-
.
Вы также должны наблюдать в текущем каталоге1image.jpg
,2image.jpg
и3image.jpg
документ. Каждый из этих файлов содержит одинаковый контентimage.jpg
.
в заключении
API Base64 — это одна из маленьких «жемчужин», представленных в Java 8. Если вам необходимо использовать Base64, вы найдете этот API очень удобным. Я призываю вас попробовать этоBase64
, начиная с методов, не описанных в этой статье.
Оригинальная ссылка:Woohoo. Java world.com/article/324…
Для получения дополнительных статей, пожалуйста, посетите: http://www.apexyun.com
Общедоступный номер: Galaxy № 1
Контактный адрес электронной почты: public@space-explore.com
(Пожалуйста, не перепечатывайте без разрешения)