Programmēšana

Base64 kodēšana un dekodēšana Java 8

Java 8 paliks atmiņā galvenokārt ar lambdas, straumju, jauna datuma / laika modeļa un Nashorn JavaScript motora ieviešanu Java. Daži atcerēsies arī Java 8, ieviešot dažādas mazas, bet noderīgas funkcijas, piemēram, Base64 API. Kas ir Base64 un kā es varu izmantot šo API? Šis ieraksts atbild uz šiem jautājumiem.

Kas ir Base64?

Bāze64 ir binārā teksta kodēšanas shēma, kas attēlo bināros datus izdrukājamā ASCII virknes formātā, pārveidojot tos radix-64 attēlojumā. Katrs Base64 cipars apzīmē tieši 6 bitu bināros datus.

Base64 pieprasījums pēc komentāru dokumentiem

Base64 pirmo reizi tika aprakstīts (bet nav nosaukts) RFC 1421: Privātuma uzlabošana interneta elektroniskajam pastam: I daļa: Ziņojumu šifrēšanas un autentifikācijas procedūras. Vēlāk tas oficiāli tika prezentēts kā Base64 RFC 2045: Daudzfunkcionāli interneta pasta paplašinājumi (MIME) pirmā daļa: Interneta ziņojumu struktūru formāts un pēc tam atkārtoti apskatīts RFC 4648: Base16, Base32 un Base64 datu kodējumi.

Base64 tiek izmantots, lai novērstu datu modificēšanu, pārvietojoties pa informācijas sistēmām, piemēram, e-pastu, kas, iespējams, nav 8 bitu tīrs (tie var izjaukt 8 bitu vērtības). Piemēram, e-pasta ziņojumam pievienojat attēlu un vēlaties, lai attēls nonāktu otrā galā, netraucējot to. Jūsu e-pasta programmatūra Base64 kodē attēlu un ievieto līdzvērtīgu tekstu ziņojumā, kā parādīts zemāk:

Saturs-izvietojums: iekļauts; filename = IMG_0006.JPG Satura Transfer-Encoding: base64 / 9j / 4R / + RXhpZgAATU0AKgAAAAgACgEPAAIAAAAGAAAAhgEQAAIAAAAKAAAAjAESAAMAAAABAAYA AAEaAAUAAAABAAAAlgEbAAUAAAABAAAAngEoAAMAAAABAAIAAAExAAIAAAAHAAAApgEyAAIAAAAU AAAArgITAAMAAAABAAEAAIdpAAQAAAABAAAAwgAABCRBcHBsZQBpUGhvbmUgNnMAAAAASAAAAAEA ... NOMbnDUk2bGh26x2yiJcsoBIrvtPe3muBbTRGMdeufmH + Nct4chUXpwSPk / qK9GtJRMWWVFbZ0JH I4rf2dkZSbOjt7hhEzwcujA4I7Gust75pYVwAPpXn + kzNLOVYD7xFegWEKPkHsM / pU1F0NKbNS32 o24sSCOlaaFYLUhjky4x9PSsKL5bJsdWkAz3xirH2dZLy1DM2C44zx1FZqL2PTXY / 9k =

Attēlā redzams, ka šis kodētais attēls sākas ar / un beidzas ar =. The ... norāda tekstu, kuru neesmu parādījis īsuma dēļ. Ņemiet vērā, ka visa šī vai jebkura cita piemēra kodēšana ir par aptuveni 33 procentiem lielāka nekā sākotnējie binārie dati.

Saņēmēja e-pasta programmatūra atšifrēs kodēto teksta attēlu, lai atjaunotu sākotnējo bināro attēlu. Šajā piemērā attēls tiks parādīts vienā rindā ar pārējo ziņojumu.

Base64 kodēšana un dekodēšana

Base64 paļaujas uz vienkāršiem kodēšanas un dekodēšanas algoritmiem. Viņi strādā ar US-ASCII 65 rakstzīmju apakškopu, kur katra no pirmajām 64 rakstzīmēm tiek attēlota līdzvērtīgā 6 bitu binārā secībā. Šeit ir alfabēts:

Vērtības kodēšana Vērtības kodēšana Vērtības kodēšana Vērtības kodēšana Vērtības kodēšana 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 (spilventiņš) = 15 P 32 g 49 x 16 Q 33 h 50 g

65. rakstzīme (=) tiek izmantots, lai īsā laikā paskaidrotu, ka Base64 kodētais teksts ir integrēts.

Apakškopas īpašums

Šai apakškopai ir svarīgs rekvizīts, ka tā tiek identiski attēlota visās ISO 646 versijās, ieskaitot US-ASCII, un visas apakškopas rakstzīmes ir identiski attēlotas arī visās EBCDIC versijās.

Kodēšanas algoritms saņem 8 bitu baitu ievades plūsmu. Tiek uzskatīts, ka šī straume tiek pasūtīta vispirms ar nozīmīgāko bitu: pirmais bits ir augstākā līmeņa bits pirmajā baitā, astotais bits ir zemākā pasūtījuma bits šajā baitā utt.

No kreisās uz labo pusi šie baiti ir sakārtoti 24 bitu grupās. Katru grupu uzskata par četrām sasaistītām 6 bitu grupām. Katra 6 bitu grupa tiek indeksēta 64 izdrukājamo rakstzīmju masīvā; iegūtais raksturs tiek izvadīts.

Ja kodējamo datu beigās ir pieejami mazāk nekā 24 biti, tiek pievienoti nulle bitu (labajā pusē), lai izveidotu 6 bitu grupu neatņemamu skaitu. Tad viens vai divi = var tikt izvadīti spilventiņu burti. Jāapsver divi gadījumi:

  • Viens atlikušais baits: Šim baitam tiek pievienoti četri nulles biti, lai izveidotu divas 6 bitu grupas. Katra grupa indeksē masīvu un tiek iegūts iegūtais raksturs. Sekojot šīm divām rakstzīmēm, divām = tiek izvadītas spilventiņu rakstzīmes.
  • Divi atlikušie baiti: divi nulles biti tiek pievienoti otrajam baitam, lai izveidotu trīs 6 bitu grupas. Katra grupa indeksē masīvu un tiek iegūts iegūtais raksturs. Sekojot šīm trim rakstzīmēm, viena = tiek izvadīts spilventiņa raksturs.

Apsvērsim trīs piemērus, lai uzzinātu, kā darbojas kodēšanas algoritms. Pirmkārt, pieņemsim, ka mēs vēlamies kodēt @!*:

Avota ASCII bitu sekvences ar iepriekš sagatavotiem 0 bitiem, lai izveidotu 8 bitu baitus: @! * 01000000 00100001 00101010 Sadalot šo 24 bitu grupu četrās 6 bitu grupās, iegūst: 010000 | 000010 | 000100 | 101010 Šie bitu modeļi ir vienādi ar šādiem indeksiem: 16 2 4 42 Indeksējot iepriekš parādītajā Base64 alfabētā, tiek iegūts šāds kodējums: QCEq

Mēs turpināsim, saīsinot ievades secību līdz @!:

Avota ASCII bitu sekvences ar iepriekš sagatavotiem 0 bitiem, lai izveidotu 8 bitu baitus: @! 01000000 00100001 Ir pievienoti divi nulles biti, lai izveidotu trīs 6 bitu grupas: 010000 | 000010 | 000100 Šie bitu modeļi ir vienādi ar šādiem indeksiem: 16 2 4 indeksēšana iepriekš parādītajā Base64 alfabētā nodrošina šādu kodējumu: QCE An = tiek izvadīts spilventiņa raksturs, iegūstot šādu galīgo kodējumu: QCE =

Pēdējais piemērs saīsina ievades secību līdz @:

Avota ASCII bitu secība ar iepriekš sagatavotiem 0 bitiem, lai izveidotu 8 bitu baitu: @ 01000000 Lai izveidotu divas 6 bitu grupas, tiek pievienoti četri nulles biti: 010000 | 000000 Šie bitu modeļi ir vienādi ar šādiem indeksiem: 16 0, indeksējot iepriekš parādītajā Base64 alfabētā, tiek iegūts šāds kodējums: QA Two = tiek izvadītas rakstzīmju rakstzīmes, iegūstot šādu galīgo kodējumu: QA ==

Dekodēšanas algoritms ir apgriezts kodēšanas algoritms. Tomēr ir brīvi rīkoties atbilstoši, ja tiek atklāts raksturs, kas nav alfabētā Base64, vai nepareizs spilventiņu skaits.

Base64 varianti

Ir izdomāti vairāki Base64 varianti. Daži varianti prasa, lai kodētā izvades plūsma būtu sadalīta vairākās fiksēta garuma līnijās, katrai līnijai nepārsniedzot noteiktu garuma ierobežojumu, un (izņemot pēdējo rindu) no līnijas atdalītāja jānodala no nākamās rindas (karietes atgriešana) \ r seko rindas padeve \ n). Es aprakstīju trīs variantus, kurus atbalsta Java 8 Base64 API. Apskatiet Wikipedia ierakstu Base64, lai iegūtu pilnu variantu sarakstu.

Pamata

RFC 4648 apraksta Base64 variantu, kas pazīstams kā Pamata. Šajā variantā kodēšanai un dekodēšanai tiek izmantots Base64 alfabēts, kas parādīts RFC 4648 un RFC 2045 1. tabulā (un parādīts iepriekš šajā ziņojumā). Kodētājs uztver kodēto izvades straumi kā vienu līniju; rindas atdalītāji netiek izvadīti. Dekoders noraida kodējumu, kurā ir rakstzīmes ārpus Base64 alfabēta. Ņemiet vērā, ka šos un citus nosacījumus var ignorēt.

MIME

RFC 2045 apraksta Base64 variantu, kas pazīstams kā MIME. Šajā variantā kodēšanai un dekodēšanai tiek izmantots Base64 alfabēts, kas parādīts RFC 2045 1. tabulā. Kodētā izvades straume ir sakārtota ne vairāk kā 76 rakstzīmju līnijās; katra līnija (izņemot pēdējo) tiek atdalīta no nākamās, izmantojot līniju atdalītāju. Dekodēšanas laikā tiek ignorēti visi rindu atdalītāji vai citas rakstzīmes, kas nav atrodamas alfabētā Base64.

URL un faila nosaukums drošs

RFC 4648 apraksta Base64 variantu, kas pazīstams kā URL un faila nosaukums drošs. Šajā variantā kodēšanai un dekodēšanai tiek izmantots Base64 alfabēts, kas parādīts RFC 4648 2. tabulā. Alfabēts ir identisks iepriekš parādītajam alfabētam, izņemot to - aizstāj + un _ aizstāj /. Netiek izvadīti līnijas atdalītāji. Dekoders noraida kodējumu, kurā ir rakstzīmes ārpus Base64 alfabēta.

Base64 kodēšana ir noderīga garu bināro datu un HTTP GET pieprasījumu kontekstā. Ideja ir kodēt šos datus un pēc tam pievienot tos HTTP GET URL. Ja tika izmantots Basic vai MIME variants, jebkurš + vai / rakstzīmēm kodētajos datos būtu jābūt URL kodētām heksadecimālajās secībās (+ kļūst % 2B un / kļūst % 2F). Iegūtā URL virkne būtu nedaudz garāka. Aizstājot + ar - un / ar _, URL un Filename Safe novērš nepieciešamību pēc URL kodētājiem / dekodētājiem (un to ietekmi uz kodēto vērtību garumiem). Šis variants ir noderīgs arī tad, ja faila nosaukumam jāizmanto kodētie dati, jo Unix un Windows failu nosaukumos nevar būt /.

Darbs ar Java Base64 API

Java 8 ieviesa Base64 API, kas sastāv no java.util.Base64 klase kopā ar tās Kodētājs un Dekoders ligzdots statisks klases. Bāze64 dāvina vairākus statisks kodētāju un dekoderu iegūšanas metodes:

  • 64. Encoder getEncoder (): Atgrieziet kodētāja variantu.
  • 64. Dekoders getDecoder (): Atgrieziet pamata varianta dekodētāju.
  • 64. Encoder getMimeEncoder (): Atgrieziet kodētāju MIME variantam.
  • 64. Enkodētājs getMimeEncoder (int lineLength, baits [] lineSeparator): Atgrieziet kodētāju modificētam MIME variantam ar norādīto lineLength (noapaļots uz leju līdz tuvākajam 4 izejas skaitlim, izvads nav sadalīts līnijās, kad lineLength<= 0) un lineSeparator. Tas met java.lang.IllegalArgumentException kad lineSeparator ietver jebkuru Base64 alfabēta rakstzīmi, kas parādīta RFC 2045 1. tabulā.

    RFC 2045 kodētājs, kas tiek atgriezts no noargumenta getMimeEncoder () metode ir diezgan stingra. Piemēram, šis kodētājs izveido kodētu tekstu ar fiksētu līniju garumu (izņemot pēdējo rindiņu) ar 76 rakstzīmēm. Ja vēlaties, lai kodētājs atbalstītu RFC 1421, kas norāda fiksētās līnijas garumu 64 rakstzīmes, jums jāizmanto getMimeEncoder (int lineLength, baits [] lineSeparator).

  • 64. Dekoders getMimeDecoder (): Atgrieziet dekodētāju MIME variantam.
  • Bāze 64. Encoder getUrlEncoder (): Atgrieziet kodētāja URL un faila nosaukums drošam variantam.
  • Base 64. Dekoders getUrlDecoder (): Atgrieziet URL un faila nosaukuma droša varianta dekodētāju.

Bāze 64. Kodētājs piedāvā vairākas threadsafe instanču metodes baitu secību kodēšanai. Nulles atsauces nodošana kādai no šīm metodēm rada: java.lang.NullPointerException:

  • baits [] kodēt (baits [] src): Kodēt visus baitus src uz nesen piešķirto baitu masīvu, ko šī metode atgriež.
  • int kodēt (baits [] src, baits [] dst): Kodēt visus baitus src uz dst (sākot ar 0 nobīdi). Ja dst nav pietiekami liels, lai turētu kodējumu, NelegālsArgumentException tiek izmests. Pretējā gadījumā uz rakstīto baitu skaits dst tiek atgriezta.
  • ByteBuffer kodējums (ByteBuffer buferis): Kodēt visus atlikušos baitus mapē buferis tikko piešķirtajam java.nio.ByteBuffer objekts. Pēc atgriešanās buferispozīcija tiks atjaunināta līdz tās robežai; tā robeža netiks mainīta. Atgrieztā izejas bufera pozīcija būs nulle, un tās ierobežojums būs iegūto kodēto baitu skaits.
  • Virkne encodeToString (baits [] src): Kodēt visus baitus src uz virkni, kas tiek atgriezta. Šīs metodes izsaukšana ir līdzvērtīga izpildei jauna virkne (kodēt (src), StandardCharsets.ISO_8859_1).
  • 64. Kodētājs bez ieliktņa (): Atgrieziet kodētāju, kas kodē līdzvērtīgi šim kodētājam, bet kodēto baitu datu beigās nepievieno nevienu pildījuma rakstzīmi.
  • OutputStream iesaiņošana (OutputStream os): Ietiniet izvades straumi baitu datu kodēšanai. Pēc lietošanas ieteicams nekavējoties aizvērt atgriezto izvades straumi, kuras laikā tā izskalos visus iespējamos atlikušos baitus uz pamatā esošo izvades straumi. Aizverot atgriezto izvades straumi, tiks aizvērta pamatā esošā izvades straume.

Bāze64. Dekoders piedāvā vairākas threadsafe instanču metodes baitu secību dekodēšanai. Nulles atsauces nodošana kādai no šīm metodēm rada: NullPointerException:

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