Programovanie

Kódovanie a dekódovanie Base64 v prostredí Java 8

Java 8 si bude pamätať hlavne kvôli zavedeniu lambdas, streamov, nového modelu dátumu a času a JavaScriptu od spoločnosti Nashorn. Niektorí si tiež pamätajú program Java 8, ktorý predstavil rôzne malé, ale užitočné funkcie, ako napríklad API Base64. Čo je Base64 a ako môžem použiť toto API? Tento príspevok odpovedá na tieto otázky.

Čo je Base64?

Base64 je schéma kódovania binárneho textu, ktorá predstavuje binárne údaje vo formáte tlačiteľného reťazca ASCII pomocou ich preloženia do reprezentácie radix-64. Každá číslica Base64 predstavuje presne 6 bitov binárnych údajov.

Base64 žiadosť o komentáre

Base64 bol prvýkrát opísaný (ale nie pomenovaný) v RFC 1421: Vylepšenie ochrany súkromia pre elektronickú poštu v internete: Časť I: Postupy šifrovania a autentifikácie správ. Neskôr bol oficiálne predstavený ako Base64 v RFC 2045: Viacúčelové rozšírenia pre internetovú poštu (MIME), Prvá časť: Formát orgánov internetových správ, a následne sa vrátil k RFC 4648: Kódovanie údajov Base16, Base32 a Base64.

Base64 sa používa na zabránenie úpravám údajov pri prenose cez informačné systémy, ako napríklad e-mail, ktoré nemusia byť 8-bitové čisté (môžu lámať 8-bitové hodnoty). Napríklad pripojíte obrázok k e-mailovej správe a chcete, aby sa obrázok dostal na druhý koniec bez toho, aby bol skomolený. Váš e-mailový softvér Base64 kóduje obrázok a vkladá ekvivalentný text do správy, ako je to znázornené nižšie:

Dispozícia obsahu: vložený; filename = IMG_0006.JPG obsah prenos kódovanie: base64 / 9j / 4R / + RXhpZgAATU0AKgAAAAgACgEPAAIAAAAGAAAAhgEQAAIAAAAKAAAAjAESAAMAAAABAAYA AAEaAAUAAAABAAAAlgEbAAUAAAABAAAAngEoAAMAAAABAAIAAAExAAIAAAAHAAAApgEyAAIAAAAU AAAArgITAAMAAAABAAEAAIdpAAQAAAABAAAAwgAABCRBcHBsZQBpUGhvbmUgNnMAAAAASAAAAAEA ... NOMbnDUk2bGh26x2yiJcsoBIrvtPe3muBbTRGMdeufmH + Nct4chUXpwSPk / qK9GtJRMWWVFbZ0JH I4rf2dkZSbOjt7hhEzwcujA4I7Gust75pYVwAPpXn + kzNLOVYD7xFegWEKPkHsM / pU1F0NKbNS32 o24sSCOlaaFYLUhjky4x9PSsKL5bJsdWkAz3xirH2dZLy1DM2C44zx1FZqL2PTXY / 9k =

Obrázok ukazuje, že tento zakódovaný obrázok začína / a končí sa =. The ... označuje text, ktorý som kvôli stručnosti nezobrazil. Upozorňujeme, že celé kódovanie pre tento alebo akýkoľvek iný príklad je asi o 33 percent väčšie ako pôvodné binárne údaje.

E-mailový softvér príjemcu dekóduje Base64 kódovaný textový obrázok, aby sa obnovil pôvodný binárny obrázok. V tomto príklade by sa obrázok zobrazil inline so zvyškom správy.

Kódovanie a dekódovanie Base64

Base64 sa spolieha na jednoduché kódovacie a dekódovacie algoritmy. Pracujú s 65-znakovou podmnožinou US-ASCII, kde sa každý z prvých 64 znakov mapuje na ekvivalentnú 6-bitovú binárnu sekvenciu. Tu je abeceda:

Kódovanie hodnoty Kódovanie hodnoty Kódovanie hodnoty Kódovanie 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 Š 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 (vložka) = 15 P 32 g 49 x 16 Q 33 h 50 r

65. znak (=) sa používa na vloženie textu kódovaného pomocou Base64 na celkovú veľkosť, ako je vysvetlené v krátkosti.

Vlastnosť podmnožiny

Táto podmnožina má dôležitú vlastnosť, že je zastúpená rovnako vo všetkých verziách ISO 646, vrátane US-ASCII, a všetky znaky v podmnožine sú rovnako zastúpené vo všetkých verziách EBCDIC.

Kódovací algoritmus prijíma vstupný tok 8-bitových bajtov. Predpokladá sa, že tento prúd je zoradený od najvýznamnejšieho bitu ako prvý: prvý bit je bit vysokého rádu v prvom bajte, ôsmy bit je bit nízkeho rádu v tomto bajte atď.

Zľava doprava sú tieto bajty usporiadané do 24-bitových skupín. Každá skupina je považovaná za štyri zreťazené 6-bitové skupiny. Každá 6-bitová skupina sa indexuje do poľa so 64 vytlačiteľnými znakmi; výsledný znak je výstupný.

Ak je na konci kódovaných údajov k dispozícii menej ako 24 bitov, pridajú sa nulové bity (vpravo), aby sa vytvoril integrálny počet 6-bitových skupín. Potom jeden alebo dva = môžu byť výstupné znaky podložky. Je potrebné vziať do úvahy dva prípady:

  • Jeden zostávajúci bajt: K tomuto bajtu sú pripojené štyri nulové bity, aby vytvorili dve 6-bitové skupiny. Každá skupina indexuje pole a na výstupe je výsledný znak. Po týchto dvoch postavách dve = znaky pad sú na výstupe.
  • Dva zostávajúce bajty: K druhému bajtu sú pripojené dva nulové bity, aby vytvorili tri 6-bitové skupiny. Každá skupina indexuje pole a na výstupe je výsledný znak. Po týchto troch postavách jedna = znak podložky je výstup.

Uvažujme o troch príkladoch, aby sme sa dozvedeli, ako funguje kódovací algoritmus. Najprv predpokladajme, že chceme kódovať @!*:

Zdrojové bitové sekvencie ASCII s vopred pripravenými 0 bitmi na vytvorenie 8-bitových bajtov: @! * 01000000 00100001 00101010 Rozdelením tejto 24-bitovej skupiny na štyri 6-bitové skupiny sa získa toto: 010000 | 000010 | 000100 | 101010 Tieto bitové vzory sa rovnajú nasledujúcim indexom: 16 2 4 42 Indexovanie do skôr zobrazenej abecedy Base64 poskytuje nasledujúce kódovanie: QCEq

Budeme pokračovať skrátením vstupnej sekvencie na @!:

Zdrojové bitové sekvencie ASCII s vopred pripravenými 0 bitmi na vytvorenie 8-bitových bajtov: @! 01000000 00100001 Dva nulové bity sú pripojené k vytvoreniu troch 6-bitových skupín: 010000 | 000010 | 000100 Tieto bitové vzory sa rovnajú nasledujúcim indexom: 16 2 4 Indexovanie do abecedy Base64, ktorá je zobrazená skôr, vedie k nasledujúcemu kódovaniu: QCE Je vydávaný znak = pad, ktorý poskytuje nasledujúce konečné kódovanie: QCE =

Posledný príklad skracuje vstupnú postupnosť na @:

Zdrojová bitová sekvencia ASCII s vopred pripravenými 0 bitmi na vytvorenie 8-bitového bajtu: @ 01000000 Štyri nulové bity sú pripojené k vytvoreniu dvoch 6-bitových skupín: 010000 | 000000 Tieto bitové vzory sa rovnajú nasledujúcim indexom: 16 0 Indexovanie do abecedy Base64 zobrazenej skôr vedie k nasledujúcemu kódovaniu: QA Dva = výstupné znaky sú výstupné, čím sa získa nasledujúce konečné kódovanie: QA ==

Dekódovací algoritmus je inverzná ku kódovaciemu algoritmu. Po zistení znaku, ktorý nie je v abecede Base64, alebo nesprávneho počtu znakov klávesnice, je však možné podniknúť príslušné kroky.

Varianty Base64

Bolo navrhnutých niekoľko variantov Base64. Niektoré varianty vyžadujú, aby sa kódovaný výstupný prúd rozdelil na viac riadkov pevnej dĺžky, pričom každý riadok neprekročí určitý limit dĺžky a (okrem posledného riadku) sa oddelí od nasledujúceho riadku pomocou oddeľovača riadkov (návrat vozíka) \ r nasledovaný riadkom \ n). Opisujem tri varianty, ktoré podporuje rozhranie Java64 Base64 API. Kompletný zoznam variantov nájdete v dokumente Wikipedia Base64.

Základné

RFC 4648 popisuje variant Base64 známy ako Základné. Tento variant používa na kódovanie a dekódovanie abecedu Base64 uvedenú v tabuľke 1 RFC 4648 a RFC 2045 (a ktorá je uvedená skôr v tomto príspevku). Kodér zaobchádza s kódovaným výstupným tokom ako s jedným riadkom; na výstupe nie sú žiadne oddeľovače riadkov. Dekodér odmieta kódovanie, ktoré obsahuje znaky mimo abecedy Base64. Upozorňujeme, že tieto a ďalšie ustanovenia môžu byť prepísané.

MIME

RFC 2045 popisuje variant Base64 známy ako MIME. Tento variant používa na kódovanie a dekódovanie abecedu Base64 uvedenú v tabuľke 1 RFC 2045. Kódovaný výstupný tok je usporiadaný do riadkov, ktoré nie sú dlhšie ako 76 znakov; každý riadok (okrem posledného riadku) je oddelený od nasledujúceho riadku pomocou oddeľovača riadkov. Všetky oddeľovače riadkov alebo iné znaky nenájdené v abecede Base64 sú počas dekódovania ignorované.

URL a názov súboru bezpečný

RFC 4648 popisuje variant Base64 známy ako URL a názov súboru bezpečný. Tento variant používa na kódovanie a dekódovanie abecedu Base64 uvedenú v tabuľke 2 RFC 4648. Abeceda je totožná s vyššie uvedenou abecedou - nahrádza + a _ nahrádza /. Na výstupe nie sú žiadne oddeľovače riadkov. Dekodér odmieta kódovanie, ktoré obsahuje znaky mimo abecedy Base64.

Kódovanie Base64 je užitočné v kontexte zdĺhavých binárnych údajov a požiadaviek HTTP GET. Cieľom je tieto údaje zakódovať a potom ich pripojiť k HTTP GET URL. Ak bol použitý variant Basic alebo MIME, akýkoľvek + alebo / znaky v kódovaných údajoch by museli byť kódované URL do hexadecimálnych sekvencií (+ sa stáva % 2B a / sa stáva % 2F). Výsledný reťazec adresy URL by bol o niečo dlhší. Výmenou + s - a / s _, URL a Filename Safe odstraňuje potrebu kódovačov / dekodérov URL (a ich dopadov na dĺžky kódovaných hodnôt). Tento variant je tiež užitočný, ak sa majú kódované údaje použiť pre názov súboru, pretože názvy súborov Unix a Windows nemôžu obsahovať /.

Práca s Java Base64 API

Java 8 predstavila API Base64 pozostávajúce z java.util.Base64 triedy spolu s jej Kódovač a Dekodér vnorené statický triedy. Base64 predstavuje niekoľko statický metódy získavania kódovacích a dekódovacích prostriedkov:

  • Base64.Encoder getEncoder (): Vrátiť kódovač pre variant Basic.
  • Base64.Decoder getDecoder (): Vrátiť dekodér pre variant Basic.
  • Base64.Encoder getMimeEncoder (): Vrátiť kódovač pre variant MIME.
  • Base64.Encoder getMimeEncoder (int lineLength, byte [] lineSeparator): Vráti kódovač pre upravený variant MIME s daným lineLength (zaokrúhlené na najbližší násobok 4 - výstup nerozdelený na riadky, keď lineLength<= 0) a lineSeparator. Vrhá to java.lang.IllegalArgumentException kedy lineSeparator zahŕňa akýkoľvek znak abecedy Base64 uvedený v tabuľke 1 RFC 2045.

    Kodér RFC 2045, ktorý sa vracia z noargumentu getMimeEncoder () metóda je dosť rigidná. Tento kódovač napríklad vytvára kódovaný text s pevnou dĺžkou riadku (okrem posledného riadku) 76 znakov. Ak chcete, aby kódovač podporoval RFC 1421, ktorý udáva pevnú dĺžku riadku 64 znakov, musíte použiť getMimeEncoder (int lineLength, byte [] lineSeparator).

  • Base64.Decoder getMimeDecoder (): Vrátiť dekodér pre variant MIME.
  • Base64.Encoder getUrlEncoder (): Vrátiť kódovač pre adresu URL a variant Filename Safe.
  • Base64.Decoder getUrlDecoder (): Vráti dekodér pre variant URL a Filename Safe.

Base64.Encoder predstavuje niekoľko metód vlákien bezpečných inštancií na kódovanie bajtových sekvencií. Výsledkom odovzdania nulového odkazu na jednu z nasledujúcich metód je java.lang.NullPointerException:

  • byte [] kódovať (byte [] src): Zakódovať všetky bajty v src na novo pridelené bajtové pole, ktoré táto metóda vráti.
  • int kódovanie (byte [] src, byte [] dst): Zakódovať všetky bajty v src do dst (počnúc offsetom 0). Ak dst nie je dosť veľký na to, aby uchoval kódovanie, IllegalArgumentException je hodená. V opačnom prípade počet zapísaných bajtov dst sa vracia.
  • Kódovanie ByteBuffer (vyrovnávacia pamäť ByteBuffer): Zakódujte všetky zostávajúce bajty do nárazník na novo pridelené java.nio.ByteBuffer objekt. Po návrate nárazníkpozícia bude aktualizovaná na svoj limit; jeho limit sa nezmení. Pozícia vrátenej výstupnej vyrovnávacej pamäte bude nulová a jej limit bude počet výsledných kódovaných bajtov.
  • Reťazec encodeToString (byte [] src): Zakódovať všetky bajty v src na reťazec, ktorý sa vráti. Vyvolanie tejto metódy je ekvivalentné vykonaniu nový reťazec (kódovanie (src), StandardCharsets.ISO_8859_1).
  • Base64.Encoder withoutPadding (): Vrátiť kódovač, ktorý kóduje rovnocenne do tohto kódovacieho zariadenia, ale bez pridania čiarky na konci kódovaných bajtových údajov.
  • Zalomenie OutputStream (výstup OS): Zabaliť výstupný prúd na kódovanie údajov bajtov. Po použití sa odporúča okamžite zavrieť vrátený výstupný prúd, počas ktorého vyprázdni všetky možné zvyšné bajty do základného výstupného toku. Uzavretím vráteného výstupného toku zavriete podkladový výstupný prúd.

Base64. Dekodér predstavuje niekoľko vláknových inštančných metód na dekódovanie bajtových sekvencií. Výsledkom odovzdania nulového odkazu na jednu z nasledujúcich metód je NullPointerException:

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