A Base64-kódolt adat méretét a bemeneti bájtok számából tudod pontosan kiszámítani. A szöveg látható betűinek száma ehhez kevés: egy ékezetes betű UTF-8 kódolással több bájtot foglalhat. Hosszabb adatoknál a növekedés közel egyharmad, rövid szövegnél a kitöltés miatt ennél jóval nagyobb is lehet.
Három bájtból négy karakter
A hagyományos Base64 három, egyenként 8 bites bájtot kezel egy csoportban. Ez 24 bit, amelyet négy, egyenként 6 bitet leíró karakterre oszt. A teljes, egyenlőségjelekkel kitöltött kimenet hossza:
Kimeneti hossz = 4 × felfelé kerekítés(bemeneti bájtszám / 3).
A felfelé kerekítés egész csoportra történik. Egy megmaradó bájthoz két kitöltőjel, két megmaradó bájthoz egy kitöltőjel tartozik. A Base64 szabványa ezt a csoportosítást és a kitöltés feltételeit írja le. A képlet a kódolt adat karaktereire vonatkozik; az esetleges sorvégeket és a köré írt adatmezőt külön kell hozzászámolnod.
Szemléltető példa: a tűz szó
A „tűz” három betű, UTF-8 kódolással azonban négy bájt: a t egy, az ű kettő, a z egy bájtot használ. A változó bájthossz hátterét az UTF-8 szabvány rögzíti.
A méretszámítás így alakul: 4 / 3 = 1,333… csoport; ezt kettőre kerekítjük; 2 × 4 = 8 kimeneti karakter. A konkrét eredmény dMWxeg==. A két záró egyenlőségjel a hiányos utolsó csoportot jelöli, a visszafejtett szöveghez egyik sem ad új betűt.
Ezt a Base64 kódoló és dekódoló két irányában is ellenőrizheted. Először kódold a szót, majd az eredményt dekódold. A jó ellenőrzés végén ugyanazt az ékezetes szöveget kapod vissza.
A DG eszköz itt UTF-8 szöveget kódol és olvas vissza. Egy kép vagy más bináris fájl szabályos Base64-alakja is visszautasítható, ha a dekódolt bájtok érvénytelen UTF-8-at alkotnak. Ezért egy ilyen hibából önmagában ne következtess sérült fájlra. A méretképlet tetszőleges bájtsorra érvényes; bináris fájl visszaellenőrzéséhez bájtokat visszaadó feldolgozó kell.
| Bemenet mérete | Csoportok száma | Kitöltött kimenet |
|---|---|---|
| 1 bájt | 1 | 4 karakter |
| 3 bájt | 1 | 4 karakter |
| 4 bájt | 2 | 8 karakter |
| 6 bájt | 2 | 8 karakter |
Egymillió bájtnál mennyi a különbség?
Vegyünk egy szemléltető, pontosan 1 000 000 bájtos adatot. Az osztás 333 333,333… csoportot ad, tehát 333 334 teljes négyes kell. A kimenet 1 333 336 karakter, ASCII-tárolással ugyanennyi bájt. A többlet 333 336 bájt, az eredeti mérethez viszonyítva 33,3336%.
Ha egy fogadó rendszer korlátja a teljes JSON-kérésre vonatkozik, a mezőnév, az idézőjelek és az egyéb adatok is beleszámítanak. Ezért egy egymillió bájtos melléklet nem fér el egy egymillió bájtos teljes kérésben, amikor a mellékletet Base64-ként küldöd.
Az adatmennyiség-átváltó használatakor az MB és MiB különbségét is tartsd meg. A NIST egységtáblája szerint 1 MB = 1 000 000 bájt, 1 MiB = 1 048 576 bájt.
Visszafelé: mekkora eredeti adat fér a korlátba?
Tegyük fel, hogy a fogadó rendszer legfeljebb 1 000 000 bájtos JSON-törzset enged. A teljes törzs egyetlen data mező, szóközök és sortörések nélkül: {"data":""}. Az üres szerkezet 11 ASCII-bájt; a két belső idézőjel közé kerül a kitöltött, sortörésmentes Base64.
Ha a teljes korlát K, az adatot körülvevő rész pedig H bájt, a legnagyobb eredeti méret:
nₘₐₓ = 3 × lefelé kerekítés[(K − H) / 4].
Ez K ≥ H esetén használható. A példában 3 × lefelé kerekítés(999 989 / 4) = 749 991 bájt. Érdemes a következő bájtot is kipróbálni, mert a kimenet négyes csoportokban nő:
| Eredeti adat | Base64 | Teljes JSON-törzs | Belefér? |
|---|---|---|---|
| 749 991 bájt | 999 988 bájt | 999 999 bájt | Igen |
| 749 992 bájt | 999 992 bájt | 1 000 003 bájt | Nem |
A 11 bájt kizárólag ehhez a minimális szerkezethez tartozik. További mező, szóköz vagy más szerializálás esetén a tényleges UTF-8 kimenetet mérd meg. HTTP-fejléceket akkor számolj hozzá, ha a szolgáltatás korlátja azokat is magában foglalja. A JSON összehasonlításáról szóló cikk segít azonosítani, mely adatok maradnak a kérésben a kódolt mező mellett.
A kérés mérete és a feldolgozás memóriaigénye
Egy 3 MiB-os, azaz 3 145 728 bájtos bemenetből pontosan 4 MiB sortörésmentes Base64 készül. Ez a továbbítandó adat mérete. A program közben több változatot is megtarthat ugyanabból az adatból.
Vegyünk egy külön tervezési példát: az eredeti 3 MiB-os bájttömb, a 4 MiB-os ASCII-kódolás és annak egy második, 4 MiB-os másolata egyszerre él a memóriában. E három adatrész együtt 11 MiB. Az objektumok, további mezők és a futtatókörnyezet ezen felül foglalnak helyet. Ez választott tárolási modell; egy valódi program szövegtárolása és másolási viselkedése eltérhet.
Ha egy 5 MiB-os kérésméretkorlát alá beférsz, abból még nem következik, hogy 5 MiB szabad memóriával is feldolgozható a fájl. Nagy adatnál mérd meg a teljes művelet csúcsmemóriáját. Darabonkénti feldolgozás akkor segít, ha a kódoló és a fogadó folyamat is támogatja, és közben sehol nem áll össze újra az egész adatsor. A négyes Base64-csoportok és a végső kitöltés kezelését ilyenkor is a választott kódolás szabályaihoz kell igazítani.
Amit a méretképlet feltételez
A Base64url változatban eltérhet két jel, és egyes felhasználások elhagyják a záró kitöltést. Sortöréseket alkalmazó formátumnál további bájtok jelennek meg. Ezeket a fogadó rendszer előírásából állapítsd meg; ne töröld automatikusan a kimenet végét.
Üres bemenethez üres kimenet tartozik. A DG dekóder a beillesztett szóközöket és sortöréseket eltávolítja, majd a kitöltést, a kanonikus Base64-alakot és az UTF-8 szöveg érvényességét vizsgálja. Hibánál ellenőrizd a másoláskor odakerült idézőjelet, a félbeszakadt utolsó csoportot és azt, hogy valóban szöveget vársz-e vissza. A fogadó API ettől eltérően kezelheti a szóközt, ezért a saját előírását is tartsd meg.
A Base64 visszafordítható kódolás, ezért a kódolt szöveg olvashatatlannak tűnő alakja nem jelent titkosítást. Mérettervezéshez az eredeti bájtszámot, átadáshoz a várt változatot, sikeres adatcseréhez pedig a visszafejtett eredményt ellenőrizd.
Záró tudáspróba
Kérdésenként egy választ jelölj meg, majd a megoldások alapján pontozd magad. Ez a három kérdés a cikkben bemutatott összefüggéseket ellenőrzi.
1. A „tűz” szó UTF-8-ban négy bájt. Hány karakter a szabályos, kitöltött, sortörés nélküli Base64?
- A) 3.
- B) 4.
- C) 8.
2. 1 000 000 bájt a teljes JSON-törzs korlátja. A Base64-adat körül 11 bájt a rögzített szerkezet, nincs extra whitespace. Legfeljebb hány eredeti bájt fér el?
- A) 750 000.
- B) 1 000 000.
- C) 749 991.
3. Egy bináris kép Base64-adata szabályos, a DG szövegdekódere mégis hibát jelez. Mi lehet az ok?
- A) A Base64 kizárólag betűket kódolhat.
- B) Minden Base64-kép titkosított.
- C) A visszaállított képbájtok nem alkotnak érvényes UTF-8 szöveget.
Megoldások és pontozás
1. C. A képlet 4 × ceil(4/3) = 8. A konkrét kimenet dMWxeg==; a kitöltés is beleszámít a kódolt méretbe. Ismétléshez: Szemléltető példa: a tűz szó.
2. C. A teljes négyes csoportoknak 999 989 bájt marad: 3 × floor(999 989/4) = 749 991. A következő eredeti bájt már újabb négyes kódolási csoportot igényel. Ismétléshez: Visszafelé: mekkora eredeti adat fér a korlátba?.
3. C. A Base64 tetszőleges bájtokat leírhat, a DG eszközének ez a módja viszont UTF-8 szöveget vár eredményként. A képfájlhoz bináris dekóder és a fájlformátum ellenőrzése kell. Ismétléshez: Szemléltető példa: a tűz szó.
Minden helyes válasz 1 pont; a hibás vagy kihagyott válasz 0 pont. Az összpontszám 0–3 lehet.
- 0 pont: dolgozd végig újra a három megoldásban megjelölt részt, és írd le a példák kiinduló feltételeit.
- 1 pont: a két elhibázott kérdésnél vezesd le a helyes választ; külön írd mellé, melyik feltétel vagy számolási lépés maradt ki.
- 2 pont: térj vissza az egyetlen elhibázott kérdéshez kapcsolt részhez, majd egy bemenet megváltoztatásával ellenőrizd újra az eredményt.
- 3 pont: a három összefüggést ebben a feladatsorban helyesen alkalmaztad. Próbáld ki a cikk egyik ellenőrzését saját adatokkal, a feltételeket és a mértékegységeket is feljegyezve.