Programování

Kódování a dekódování Base64 v Javě 8

Java 8 bude pamatována hlavně pro zavedení lambdas, streamů, nového modelu data a času a nashornského JavaScriptu do Javy. Někteří si také zapamatují prostředí Java 8 pro zavedení různých malých, ale užitečných funkcí, jako je API Base64. Co je Base64 a jak mohu použít toto API? Tento příspěvek odpovídá na tyto otázky.

Co je Base64?

Base64 je schéma kódování binárního textu, které představuje binární data ve formátu řetězce ASCII pro tisk tak, že je převádí na reprezentaci radix-64. Každá číslice Base64 představuje přesně 6 bitů binárních dat.

Base64 žádost o dokumenty komentářů

Base64 byl poprvé popsán (ale nebyl pojmenován) v RFC 1421: Vylepšení ochrany soukromí pro elektronickou poštu v Internetu: Část I: Postupy šifrování a autentizace zpráv. Později byl oficiálně představen jako Base64 v RFC 2045: Multipurpose Internet Mail Extensions (MIME) Část první: Formát subjektů internetových zpráv a následně znovu v RFC 4648: Base16, Base32 a Base64 Data Encodings.

Base64 se používá k zabránění úpravám dat během přenosu prostřednictvím informačních systémů, jako je e-mail, které nemusí být 8bitové čisté (mohou zkomplikovat 8bitové hodnoty). Například připojíte obrázek k e-mailové zprávě a chcete, aby obrázek dorazil na druhý konec, aniž by byl poškozený. Váš e-mailový software Base64 kóduje obrázek a vloží ekvivalentní text do zprávy, jak je znázorněno níže:

Dispozice obsahu: vložená; filename = IMG_0006.JPG obsah přenos kódování: base64 / 9j / 4R / + RXhpZgAATU0AKgAAAAgACgEPAAIAAAAGAAAAhgEQAAIAAAAKAAAAjAESAAMAAAABAAYA AAEaAAUAAAABAAAAlgEbAAUAAAABAAAAngEoAAMAAAABAAIAAAExAAIAAAAHAAAApgEyAAIAAAAU AAAArgITAAMAAAABAAEAAIdpAAQAAAABAAAAwgAABCRBcHBsZQBpUGhvbmUgNnMAAAAASAAAAAEA ... NOMbnDUk2bGh26x2yiJcsoBIrvtPe3muBbTRGMdeufmH + Nct4chUXpwSPk / qK9GtJRMWWVFbZ0JH I4rf2dkZSbOjt7hhEzwcujA4I7Gust75pYVwAPpXn + kzNLOVYD7xFegWEKPkHsM / pU1F0NKbNS32 o24sSCOlaaFYLUhjky4x9PSsKL5bJsdWkAz3xirH2dZLy1DM2C44zx1FZqL2PTXY / 9k =

Obrázek ukazuje, že tento zakódovaný obrázek začíná / a končí =. The ... označuje text, který jsem kvůli stručnosti nezobrazil. Všimněte si, že celé kódování pro tento nebo jakýkoli jiný příklad je přibližně o 33 procent větší než původní binární data.

E-mailový software příjemce dekóduje Base64 kódovaný textový obrázek a obnoví tak původní binární obrázek. V tomto příkladu by se obrázek zobrazil inline se zbytkem zprávy.

Kódování a dekódování Base64

Base64 spoléhá na jednoduché kódovací a dekódovací algoritmy. Pracují s 65znakovou podmnožinou US-ASCII, kde se každý z prvních 64 znaků mapuje na ekvivalentní 6bitovou binární sekvenci. Zde je abeceda:

Kódování hodnoty Kódování hodnoty Kódování hodnoty Kódování hodnoty 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 (podložka) = 15 P 32 g 49 x 16 Q 33 h 50 y

65. znak (=) se používá k vložení textu kódovaného pomocí Base64 do integrální velikosti, jak bude vysvětleno níže.

Vlastnost podmnožiny

Tato podmnožina má důležitou vlastnost, že je zastoupena identicky ve všech verzích ISO 646, včetně US-ASCII, a všechny znaky v podmnožině jsou také reprezentovány shodně ve všech verzích EBCDIC.

Kódovací algoritmus přijímá vstupní proud 8bitových bajtů. Předpokládá se, že tento proud je nejprve objednán s nejvýznamnějším bitem: první bit je bit nejvyššího řádu v prvním bajtu, osmý bit je bit nízkého řádu v tomto bajtu atd.

Zleva doprava jsou tyto bajty organizovány do 24bitových skupin. Každá skupina je považována za čtyři zřetězené 6bitové skupiny. Každá 6bitová skupina se indexuje do pole 64 tisknutelných znaků; výsledný znak je výstup.

Když je na konci kódovaných dat k dispozici méně než 24 bitů, přidají se nulové bity (vpravo), aby se vytvořil integrální počet 6bitových skupin. Potom jeden nebo dva = mohou být na výstupu znaky podložky. Je třeba vzít v úvahu dva případy:

  • Jeden zbývající bajt: K tomuto bajtu jsou připojeny čtyři nulové bity, které tvoří dvě 6bitové skupiny. Každá skupina indexuje pole a na výstupu je výsledný znak. V návaznosti na tyto dva znaky, dva = znaky pad jsou na výstupu.
  • Dva zbývající bajty: K druhému bajtu jsou připojeny dva nulové bity, které tvoří tři 6bitové skupiny. Každá skupina indexuje pole a na výstupu je výsledný znak. V návaznosti na tyto tři postavy, jeden = znak pad je výstup.

Zvažme tři příklady, abychom se dozvěděli, jak kódovací algoritmus funguje. Nejprve předpokládejme, že chceme kódovat @!*:

Zdrojové bitové sekvence ASCII s předpřipravenými 0 bity pro vytvoření 8bitových bajtů: @! * 01000000 00100001 00101010 Rozdělení této 24bitové skupiny na čtyři 6bitové skupiny poskytne následující: 010000 | 000010 | 000100 | 101010 Tyto bitové vzory odpovídají následujícím indexům: 16 2 4 42 Indexování do abecedy Base64 zobrazené výše poskytuje následující kódování: QCEq

Pokračujeme zkrácením vstupní sekvence na @!:

Zdrojové bitové sekvence ASCII s předpřipravenými 0 bity pro vytvoření 8bitových bajtů: @! 01000000 00100001 Dva nulové bity jsou připojeny k vytvoření tří 6bitových skupin: 010000 | 000010 | 000100 Tyto bitové vzory se rovnají následujícím indexům: 16 2 4 Indexování do abecedy Base64 zobrazené dříve přináší následující kódování: QCE An = je vyplněn znak pad, který poskytuje následující konečné kódování: QCE =

Poslední příklad zkracuje vstupní sekvenci na @:

Zdrojová bitová sekvence ASCII s předpřipravenými 0 bity pro vytvoření 8bitového bajtu: @ 01000000 K vytvoření dvou 6bitových skupin jsou připojeny čtyři nulové bity: 010000 | 000000 Tyto bitové vzory odpovídají následujícím indexům: 16 0 Indexování do abecedy Base64 zobrazené dříve přináší následující kódování: QA Dva = jsou vyplněny znaky pad, čímž je získáno následující konečné kódování: QA ==

Dekódovací algoritmus je inverzní k kódovacímu algoritmu. Po detekci znaku, který není v abecedě Base64, nebo nesprávného počtu znaků na podložce, je však možné provést příslušnou akci.

Varianty Base64

Bylo navrženo několik variant Base64. Některé varianty vyžadují, aby byl kódovaný výstupní proud rozdělen na několik řádků pevné délky, přičemž každý řádek nepřesahuje určitou délkovou hranici a (s výjimkou posledního řádku) je oddělen od dalšího řádku pomocí oddělovače řádků (návrat vozíku) \ r následuje řádkování \ n). Popisuji tři varianty, které jsou podporovány rozhraním Base64 API Java 8. Podívejte se na záznam Wikipedie Base64, kde najdete kompletní seznam variant.

Základní

RFC 4648 popisuje variantu Base64 známou jako Základní. Tato varianta používá pro kódování a dekódování abecedu Base64 uvedenou v tabulce 1 RFC 4648 a RFC 2045 (a ukázaná dříve v tomto příspěvku). Kodér považuje kódovaný výstupní proud za jeden řádek; na výstupu nejsou žádné oddělovače řádků. Dekodér odmítá kódování, které obsahuje znaky mimo abecedu Base64. Upozorňujeme, že tato a další ustanovení lze přepsat.

MIM

RFC 2045 popisuje variantu Base64 známou jako MIM. Tato varianta používá pro kódování a dekódování abecedu Base64 uvedenou v tabulce 1 RFC 2045. Zakódovaný výstupní proud je uspořádán do řádků o délce maximálně 76 znaků; každý řádek (kromě posledního řádku) je oddělen od dalšího řádku pomocí oddělovače řádků. Všechny oddělovače řádků nebo jiné znaky, které nebyly nalezeny v abecedě Base64, jsou během dekódování ignorovány.

URL a název souboru v bezpečí

RFC 4648 popisuje variantu Base64 známou jako URL a název souboru v bezpečí. Tato varianta používá pro kódování a dekódování abecedu Base64 uvedenou v tabulce 2 RFC 4648. Abeceda je totožná s abecedou zobrazenou dříve, kromě toho - nahrazuje + a _ nahrazuje /. Na výstupu nejsou žádné oddělovače řádků. Dekodér odmítá kódování, které obsahuje znaky mimo abecedu Base64.

Kódování Base64 je užitečné v kontextu zdlouhavých binárních dat a požadavků HTTP GET. Myšlenkou je zakódovat tato data a poté je připojit k HTTP GET URL. Pokud byla použita základní nebo MIME varianta, libovolná + nebo / znaky v zakódovaných datech by musely být zakódovány URL do hexadecimálních sekvencí (+ se stává % 2B a / se stává % 2F). Výsledný řetězec URL by byl o něco delší. Výměnou + s - a / s _, URL a Filename Safe odstraňuje potřebu kodérů / dekodérů URL (a jejich dopadů na délku kódovaných hodnot). Tato varianta je také užitečná, pokud mají být kódovaná data použita pro název souboru, protože názvy souborů Unix a Windows nemohou obsahovat /.

Práce s Java Base64 API

Java 8 představila API Base64 skládající se z java.util.Base64 třídy spolu s jeho Kodér a Dekodér vnořené statický třídy. Base64 představuje několik statický metody pro získání kodérů a dekodérů:

  • Base64.Encoder getEncoder (): Vrátí kodér pro základní variantu.
  • Base64.Decoder getDecoder (): Vrátí dekodér pro základní variantu.
  • Base64.Encoder getMimeEncoder (): Vrátí kodér pro variantu MIME.
  • Base64.Encoder getMimeEncoder (int lineLength, byte [] lineSeparator): Vrátí kodér pro upravenou variantu MIME s daným lineLength (zaokrouhleno dolů na nejbližší násobek 4 - výstup nerozdělen do řádků, když lineLength<= 0) a lineSeparator. Hází to java.lang.IllegalArgumentException když lineSeparator zahrnuje jakýkoli znak abecedy Base64 uvedený v tabulce 1 RFC 2045.

    Kodér RFC 2045, který je vrácen z noargumentu getMimeEncoder () metoda, je poměrně rigidní. Například tento kodér vytváří kódovaný text s pevnými délkami řádků (kromě posledního řádku) 76 znaků. Pokud chcete, aby kodér podporoval RFC 1421, který určuje pevnou délku řádku 64 znaků, musíte použít getMimeEncoder (int lineLength, byte [] lineSeparator).

  • Base64.Decoder getMimeDecoder (): Vrátit dekodér pro variantu MIME.
  • Base64.Encoder getUrlEncoder (): Vrátí kodér pro variantu URL a Filename Safe.
  • Base64.Decoder getUrlDecoder (): Vrátí dekodér pro variantu URL a bezpečný název souboru.

Base64.Encoder představuje několik metod instance bezpečných vláken pro kódování bajtových sekvencí. Předání nulového odkazu na jednu z následujících metod má za následek java.lang.NullPointerException:

  • byte [] kódování (byte [] src): Zakódujte všechny bajty do src na nově přidělené bajtové pole, které tato metoda vrátí.
  • int kódování (byte [] src, byte [] dst): Zakódujte všechny bajty do src na dst (počínaje offsetem 0). Li dst není dost velký na to, aby udržel kódování, IllegalArgumentException je hozen. Jinak počet zapsaných bajtů dst je vrácen.
  • ByteBuffer encode (ByteBuffer buffer): Zakódujte všechny zbývající bajty do nárazník do nově přiděleného java.nio.ByteBuffer objekt. Po návratu nárazníkPozice bude aktualizována na svůj limit; jeho limit se nezměnil. Pozice vráceného výstupního bufferu bude nula a jeho limit bude počet výsledných kódovaných bajtů.
  • Řetězec encodeToString (byte [] src): Zakódujte všechny bajty do src na řetězec, který je vrácen. Vyvolání této metody je ekvivalentní provedení new String (encode (src), StandardCharsets.ISO_8859_1).
  • Base64.Encoder withoutPadding (): Vrátí kodér, který kóduje ekvivalentně tomuto kodéru, ale bez přidání jakéhokoli znaku polstrování na konec kódovaných dat bajtu.
  • Omotání OutputStream (výstup OS): Zabalit výstupní proud pro kódování dat bajtů. Po použití se doporučuje okamžitě zavřít vrácený výstupní proud, během kterého vyprázdní všechny možné zbylé bajty do podkladového výstupního proudu. Uzavřením vráceného výstupního proudu zavřete podkladový výstupní proud.

Base64. Dekodér představuje několik podprocesových instančních metod pro dekódování bajtových sekvencí. Předání nulového odkazu na jednu z následujících metod má za následek NullPointerException:

$config[zx-auto] not found$config[zx-overlay] not found