Programiranje

Kodiranje in dekodiranje Base64 v Javi 8

Java 8 si bomo zapomnili predvsem po uvajanju lambdas, tokov, novega modela datuma / časa in mehanizma JavaScript Nashorn v Javo. Nekateri si bodo Java 8 zapomnili tudi po uvedbi različnih majhnih, a uporabnih funkcij, kot je API Base64. Kaj je Base64 in kako lahko uporabim ta API? Ta objava odgovarja na ta vprašanja.

Kaj je Base64?

Base64 je shema kodiranja binarnega besedila, ki predstavlja binarne podatke v natisljivi obliki zapisa ASCII tako, da jih prevede v predstavitev radix-64. Vsaka številka Base64 predstavlja natanko 6 bitov binarnih podatkov.

Zahteva Base64 za dokumente s komentarji

Base64 je bil prvič opisan (vendar ni imenovan) v RFC 1421: Izboljšanje zasebnosti za elektronsko pošto v internetu: I. del: Postopki šifriranja in avtentikacije sporočil. Kasneje je bil uradno predstavljen kot Base64 v RFC 2045: Večnamenske razširitve internetne pošte (MIME), prvi del: Oblika internetnih sporočil, nato pa je bil ponovno pregledan v RFC 4648: Kodiranja podatkov Base16, Base32 in Base64.

Base64 se uporablja za preprečevanje spreminjanja podatkov med prenosom prek informacijskih sistemov, kot je e-pošta, ki morda niso 8-bitni čisti (morda okrasijo 8-bitne vrednosti). Na primer, e-poštnemu sporočilu priložite sliko in želite, da slika prispe na drugi konec, ne da bi bila popačena. Vaša e-poštna programska oprema Base64 kodira sliko in v sporočilo vstavi enakovredno besedilo, kot je prikazano spodaj:

Razporeditev vsebine: v vrstici; naziv = IMG_0006.JPG Content-Transfer-Encoding: base64 / 9j / 4R / + RXhpZgAATU0AKgAAAAgACgEPAAIAAAAGAAAAhgEQAAIAAAAKAAAAjAESAAMAAAABAAYA AAEaAAUAAAABAAAAlgEbAAUAAAABAAAAngEoAAMAAAABAAIAAAExAAIAAAAHAAAApgEyAAIAAAAU AAAArgITAAMAAAABAAEAAIdpAAQAAAABAAAAwgAABCRBcHBsZQBpUGhvbmUgNnMAAAAASAAAAAEA ... NOMbnDUk2bGh26x2yiJcsoBIrvtPe3muBbTRGMdeufmH + Nct4chUXpwSPk / qK9GtJRMWWVFbZ0JH I4rf2dkZSbOjt7hhEzwcujA4I7Gust75pYVwAPpXn + kzNLOVYD7xFegWEKPkHsM / pU1F0NKbNS32 o24sSCOlaaFYLUhjky4x9PSsKL5bJsdWkAz3xirH2dZLy1DM2C44zx1FZqL2PTXY / 9k =

Na sliki je razvidno, da se ta kodirana slika začne z / in se konča z =. The ... označuje besedilo, ki ga nisem kratko prikazal. Upoštevajte, da je celotno kodiranje za ta ali kateri koli drug primer približno 33 odstotkov večje od prvotnih binarnih podatkov.

Prejemnikova e-poštna programska oprema bo Base64 dekodirala kodirano besedilno sliko, da obnovi prvotno binarno sliko. V tem primeru bi bila slika prikazana v vrstici s preostalim delom sporočila.

Kodiranje in dekodiranje Base64

Base64 se opira na preproste algoritme za kodiranje in dekodiranje. Delajo s 65-mestno podmnožico US-ASCII, kjer se vsak od prvih 64 znakov preslika v enakovredno 6-bitno binarno zaporedje. Tu je abeceda:

Kodiranje vrednosti Kodiranje vrednosti Kodiranje vrednosti Kodiranje vrednosti 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 V 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 (blazinica) = 15 P 32 g 49 x 16 Q 33 h 50 y

65. znak (=) se uporablja za dodajanje besedila, kodiranega z Base64, v celotno velikost, kot je razloženo v kratkem.

Lastnost podnabora

Ta podnabor ima pomembno lastnost, da je enako predstavljen v vseh različicah ISO 646, vključno z US-ASCII, vsi znaki v podmnožici pa so enako predstavljeni v vseh različicah EBCDIC.

Algoritem kodiranja prejme vhodni tok 8-bitnih bajtov. Predpostavlja se, da je ta tok razvrščen z najpomembnejšim bitom prvi: prvi bit je bit visokega reda v prvem bajtu, osmi bit je bit nizkega reda v tem bajtu itd.

Ti bajti so od leve proti desni organizirani v 24-bitne skupine. Vsaka skupina se obravnava kot štiri združene 6-bitne skupine. Vsaka 6-bitna skupina indeksira v niz od 64 tiskljivih znakov; izhodni znak se izpiše.

Ko je na koncu kodiranih podatkov na voljo manj kot 24 bitov, se doda nič bitov (na desni), da se tvori celotno število 6-bitnih skupin. Potem pa eno ali dve = znaki pad lahko izpišejo. Upoštevati je treba dva primera:

  • Preostali bajt: Štiri nič bitne točke se dodajo temu bajtu, da tvorijo dve 6-bitni skupini. Vsaka skupina indeksira matriko in iz nje se izpiše nastali znak. Po teh dveh znakih dva = izhajajo znaki pad.
  • Dva preostala bajta: Dvema nič bitoma sta dodana drugemu bajtu, da se tvorijo tri 6-bitne skupine. Vsaka skupina indeksira matriko in iz nje se izpiše nastali znak. Po teh treh znakih še en = izpiše se znak pad.

Oglejmo si tri primere, da se naučimo, kako deluje algoritem kodiranja. Najprej domnevamo, da želimo kodirati @!*:

Izvorna ASCII bitna zaporedja z vnaprej dodanimi 0 bitov v 8-bitne bajte: @! * 01000000 00100001 00101010 Če delimo to 24-bitno skupino na štiri 6-bitne skupine, dobimo naslednje: 010000 | 000010 | 000100 | 101010 Ti bitni vzorci so enaki naslednjim indeksom: 16 2 4 42 Indeksiranje v abecedo Base64, prikazano prej, daje naslednje kodiranje: QCEq

Nadaljevali bomo s skrajšanjem vhodnega zaporedja na @!:

Izvorna ASCII bitna zaporedja z vnaprej dodanimi 0 bitov v 8-bitne bajte: @! 01000000 00100001 Dve nič bit sta dodana, da dobimo tri 6-bitne skupine: 010000 | 000010 | 000100 Ti bitni vzorci so enaki naslednjim indeksom: 16 2 4 Indeksiranje v abecedo Base64, prikazano prej, daje naslednje kodiranje: QCE Izpiše se znak = pad, ki da naslednje končno kodiranje: QCE =

Zadnji primer skrajša vhodno zaporedje na @:

Izvorno ASCII bitno zaporedje z vnaprej dodanimi 0 bitov, da se tvori 8-bitni bajt: @ 01000000 Štirje nič bitov so dodani, da dobimo dve 6-bitni skupini: 010000 | 000000 Ti bitni vzorci se enačijo z naslednjimi indeksi: 16 0 Indeksiranje v abecedo Base64, prikazano prej, daje naslednje kodiranje: QA Izpišeta se dva = znaka padca, kar da naslednje končno kodiranje: QA ==

Algoritem dekodiranja je inverzen algoritmu kodiranja. Vendar lahko brezplačno ustrezno ukrepate, ko zaznate znak, ki ni v abecedi Base64, ali nepravilno število znakov pad.

Različice Base64

Izdelanih je bilo več različic Base64. Nekatere različice zahtevajo, da se kodirani izhodni tok razdeli na več vrstic fiksne dolžine, pri čemer vsaka vrstica ne presega določene omejitve dolžine in je (razen zadnje vrstice) ločena od naslednje vrstice prek ločevalnika vrstic (vrnitev nosilca). \ r čemur sledi linefeed \ n). Opisujem tri različice, ki jih podpira Base64 API Java 8. Za celoten seznam različic si oglejte Wikipedia's Base64.

Osnovno

RFC 4648 opisuje različico Base64, znano kot Osnovno. Ta različica za kodiranje in dekodiranje uporablja abecedo Base64, predstavljeno v tabeli 1 RFC 4648 in RFC 2045 (in prikazano prej v tej objavi). Dajalnik kodirani izhodni tok obravnava kot eno vrstico; se ne izpišejo ločila vrstic. Dekoder zavrne kodiranje, ki vsebuje znake zunaj abecede Base64. Upoštevajte, da je te in druge določbe mogoče preglasiti.

MIME

RFC 2045 opisuje različico Base64, znano kot MIME. Ta različica za kodiranje in dekodiranje uporablja abecedo Base64, predstavljeno v tabeli 1 RFC 2045. Kodiran izhodni tok je organiziran v vrstice, ki ne vsebujejo več kot 76 znakov; vsaka vrstica (razen zadnje vrstice) je ločena od naslednje vrstice prek ločila. Vsa ločila vrstic ali drugi znaki, ki jih ni mogoče najti v abecedi Base64, se med dekodiranjem prezrejo.

URL in ime datoteke varno

RFC 4648 opisuje različico Base64, znano kot URL in ime datoteke varno. Ta različica za kodiranje in dekodiranje uporablja abecedo Base64, predstavljeno v tabeli 2 RFC 4648. Abeceda je enaka abecedi, prikazani prej, razen te - nadomešča + in _ nadomešča /. Izhod ni ločila vrstic. Dekoder zavrne kodiranje, ki vsebuje znake zunaj abecede Base64.

Kodiranje Base64 je koristno v okviru dolgih binarnih podatkov in HTTP GET zahtev. Ideja je kodirati te podatke in jih nato dodati URL-ju HTTP GET. Če je bila uporabljena različica Basic ali MIME, katera koli + ali / znaki v kodiranih podatkih bi morali biti kodirani po URL-ju v šestnajstiška zaporedja (+ postane % 2B in / postane % 2F). Nastali niz URL-ja bi bil nekoliko daljši. Z zamenjavo + s - in / s _, URL in File File Safe odpravlja potrebo po kodirnikih / dekodirnikih URL-jev (in njihovih vplivih na dolžine kodiranih vrednosti). Ta varianta je uporabna tudi, kadar naj se kodirani podatki uporabljajo za ime datoteke, ker imena datotek Unix in Windows ne moreta vsebovati /.

Delo z Java's Base64 API

Java 8 je predstavil API Base64, sestavljen iz java.util.Base64 razred skupaj s svojimi Dajalnik in Dekodirnik ugnezdena statično razredih. Base64 predstavlja več statično metode za pridobivanje kodirnikov in dekoderjev:

  • Base64.Encoder getEncoder (): Vrni kodirnik za osnovno različico.
  • Base64.Decoder getDecoder (): Vrni dekodirnik za osnovno različico.
  • Base64.Encoder getMimeEncoder (): Vrni kodirnik za različico MIME.
  • Base64.Encoder getMimeEncoder (int lineLength, byte [] lineSeparator): Vrni kodirnik za spremenjeno različico MIME z dano lineLength (zaokroženo navzdol na najbližji večkratnik 4 - izhod ni ločen v vrstice, ko lineLength<= 0) in lineSeparator. Vrže java.lang.IllegalArgumentException kdaj lineSeparator vključuje kateri koli znak abecede Base64, predstavljen v tabeli 1 RFC 2045.

    Kodirnik RFC 2045, ki se vrne iz argumenta getMimeEncoder () metoda je precej toga. Na primer, ta kodirnik ustvari kodirano besedilo s fiksno dolžino vrstic (razen zadnje vrstice) s 76 znaki. Če želite, da kodirnik podpira RFC 1421, ki označuje fiksno dolžino črte 64 znakov, morate uporabiti getMimeEncoder (int lineLength, byte [] lineSeparator).

  • Base64.Decoder getMimeDecoder (): Vrni dekodirnik za različico MIME.
  • Base64.Encoder getUrlEncoder (): Vrnite kodirnik za različico varnega URL-ja in imena datotek.
  • Base64.Decoder getUrlDecoder (): Vrnite dekoder za različico URL in varno ime datoteke.

Base64. Enkoder predstavlja več metod varnih nitkov za kodiranje bajtnih zaporedij. Posredovanje ničelne reference na enega od naslednjih načinov povzroči java.lang.NullPointerException:

  • byte [] kodiranje (byte [] src): Kodiraj vse bajte v src na novo dodeljeno matriko bajtov, ki jo ta metoda vrne.
  • kodiranje int (bajt [] src, bajt [] dst): Kodiraj vse bajte v src do dst (začenši z odmikom 0). Če dst ni dovolj velik za kodiranje, IllegalArgumentException je vržen. V nasprotnem primeru število bajtov, zapisanih v dst se vrne.
  • Kodiranje ByteBuffer (medpomnilnik ByteBuffer): Kodiraj vse preostale bajte v medpomnilnik na novo dodeljeno java.nio.ByteBuffer predmet. Po vrnitvi, medpomnilnikpoložaj osebe bo posodobljen do svoje meje; njegova meja ne bo spremenjena. Položaj vrnjenega izhodnega medpomnilnika bo enak nič, njegova omejitev pa bo število posledično kodiranih bajtov.
  • String encodeToString (bajt [] src): Kodiraj vse bajte v src v niz, ki se vrne. Priklic te metode je enakovreden izvajanju nov niz (kodiraj (src), StandardCharsets.ISO_8859_1).
  • Base64. Encoder withoutPadding (): Vrnite kodirnik, ki kodira enakovredno temu kodirniku, vendar brez dodajanja znakov za oblazinjenje na koncu kodiranih bajtnih podatkov.
  • OutputStream wrap (OutputStream os): Zavijte izhodni tok za kodiranje bajtnih podatkov. Priporočljivo je, da vrnjeni izhodni tok po uporabi takoj zaprete, med tem pa bo splaknil vse možne ostanke bajtov v osnovni izhodni tok. Zapiranje vrnjenega izhodnega toka bo zaprlo osnovni izhodni tok.

Base64.Dekoder predstavlja več metod varnih primerkov za dekodiranje bajtnih zaporedij. Posredovanje ničelne reference na enega od naslednjih načinov povzroči NullPointerException:

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