क्या आपको Base64 फ़ॉर्मेट के साथ काम करना होता है? तो यह साइट आपके लिए एकदम सही है! अपने डेटा को एन्कोड या डिकोड करने के लिए, हमारे बेहद आसान ऑनलाइन टूल का इस्तेमाल करें।

Kotlin में Base64 डिकोडिंग: एक सम्पूर्ण गाइड

आप एक ऐसी वैल्यू को घूर रहे हैं जो पढ़ने से इंकार कर रही है: SGVsbG8sIFdvcmxkIQ==। अक्षरों और अंकों की एक सिलसिला, बीच-बीच में कभी + या /, और आमतौर पर आख़िर में लटके एक-दो = चर। यह Base64 है, और यह गाइड इसी के बारे में है कि इसे वापस उसमें बदला जाए जो वह पहले था - एक वाक्य, एक इमेज, एक सर्टिफ़िकेट, एक बायनेरी ब्लॉब - Kotlin के तरीके से। शुरू करने से पहले एक-लाइन रिफ़्रेशर: Base64 हर तीन बाइट्स को 64-चिह्नों की वर्णमाला से लिए चार चरों में पैक करता है, और आख़िर में = पैडिंग की एक छोटी पूंछ बताती है कि असली डेटा कहाँ ख़त्म हुआ। पूरा फ़ॉर्मैट दौर होम पेज पर मिलता है, इसलिए यहाँ बस एक वाक्य खर्च करते हैं, और एक और: चार चर तीन बाइट्स का बोझ उठाते हैं, इसलिए टेक्स्ट शक्ल मूल डेटा से करीब एक-तिहाई लंबी होती है।

Kotlin की अच्छी ख़बर: आपको कोई पैकेज भी ज़रूरत नहीं है। स्टैंडर्ड लाइब्रेरी सालों से अपना खुद का Base64 इम्प्लीमेंटेशन साथ ला रही है; Kotlin 2.2 से वह पूरी तरह स्टेबल है, और यह हर प्लेटफ़ॉर्म पर चलता है जहाँ Kotlin चलता है - आपकी लैपटॉप की JVM से Android फ़ोन तक, Node.js से WASI एज फ़ंक्शन तक। नीचे की हर चीज़ आपके प्रोजेक्ट के साथ आने वाले Kotlin पर काम करती है।

पहले अच्छी ख़बर: आपको असल में क्या चाहिए

Gradle में जोड़ने के लिए कोई base64 आर्टिफैक्ट नहीं है, कोई NuGet-स्टाइल पैकेज नहीं, कोई npm मॉड्यूल नहीं। जिस क्लास की आपको ज़रूरत है वह है kotlin.io.encoding.Base64, जो खुद Kotlin स्टैंडर्ड लाइब्रेरी का हिस्सा है। अगर आप println लिख सकते हैं, तो आप Base64 डिकोड भी कर सकते हैं। एक Kotlin प्रोजेक्ट में Base64 का काम तीन APIs कर सकती हैं, और सही एक चुनना पहला असली फैसला है:

API कहाँ चलती है इसे कब चुनें
kotlin.io.encoding.Base64 हर Kotlin प्लेटफ़ॉर्म: JVM, Android, JS, Native, Wasm डिफ़ॉल्ट विकल्प। Kotlin 2.2 से स्टेबल, मल्टीप्लेटफ़ॉर्म, मॉडर्न API
java.util.Base64 सिर्फ़ JVM (Java 8+; Android पर API 26+) जो कोडबेस JVM-only हैं और पहले से Java इंटरॉप की दुनिया में रहते हैं
android.util.Base64 सिर्फ़ Android (API 8+) लेगासी Android कोड, या जब आपको उसके फ़्लैग कॉन्स्टेंट्स की ख़ास ज़रूरत हो

दो वर्ज़न नोट्स जानने लायक हैं। पहला: स्टैंडर्ड लाइब्रेरी की यह क्लास पहली बार Kotlin 1.8.20 (अप्रैल 2023) में @ExperimentalEncodingApi गेट के पीछे आई; Kotlin 2.0.20 ने withPadding डायल और सख़्त पैडिंग नियम लाया, और Kotlin 2.2.0 (जून 2025) ने API को स्टेबल बनाया और PEM इंस्टेंस जोड़ी। मतलब Kotlin 2.2 या नए पर - शामिल है वर्तमान स्टेबल लाइन, 2.4.x - आप इस गाइड की हर चीज़ ज़ीरो एनोटेशन के साथ इस्तेमाल कर सकते हैं। दूसरा: अगर आपका प्रोजेक्ट 1.8 और 2.1 के बीच किसी Kotlin वर्ज़न पर पिन है, तो वही क्लास मौजूद है लेकिन एक्सपेरिमेंटल चिह्नित है, और कंपाइलर फ़ंक्शन पर @OptIn एनोटेशन के बिना आपको उसे इस्तेमाल करने ही नहीं देगा।

एक इंस्टॉलेशन फँसाव जिसने एक से ज़्यादा दोपहरें ख़त्म कर दी हैं: Debian और Ubuntu रिपॉज़िटोरिज़ में kotlin पैकेज वर्ज़न 1.3.31 है, जो स्टैंडर्ड लाइब्रेरी के Base64 API से पूरी तरह पहले का है, इसलिए वह इस लेख का एक उदाहरण भी कंपाइल नहीं कर सकता। बजाय रिपॉज़िटोरि वाले पैकेज के कंपाइलर GitHub की Kotlin रिलीज़ से या SDKMAN से लीजिए, और Gradle प्रोजेक्ट्स में प्लगइन एक्सप्लिसिटली पिन कीजिए:

plugins {
  kotlin("jvm") version "2.4.10"
}

आपका पहला डिकोड: दो पंक्तियाँ और बाइट्स का रिज़ल्ट

पूरी रस्म दो स्टेटमेंट्स में समा जाती है, और क्लासिक TWFu स्ट्रिंग से शुरू करने जैसा कुछ बेहतर नहीं है:

import kotlin.io.encoding.Base64
fun main() {
  val packed = "TWFu"
  val bytes = Base64.decode(packed)
  println(bytes.decodeToString())  // Man
}

इसे धीरे-धीरे पढ़िए, क्योंकि इसमें तीन डिज़ाइन फैसले छिपे हैं। पहली: .Default के बिना Base64.decode(...) कोई टाइपो नहीं है: Default इस क्लास का कॉम्पैनिऑन ऑबजैक्ट है, इसलिए क्लास पर सीधे फ़ंक्शन कॉल करना Base64.Default पर कॉल करने का शॉर्टहांड है। पुराने ट्यूटोरियल्स में आपको Base64.Default.decode(...) भी दिखेगा, और इसका मतलब बिल्कुल वही है। दूसरी, और यह दिखने से ज़्यादा ज़रूरी है: decode आपको ByteArray सौंपता है, कभी String नहीं। पेलोड एक JPEG, एक X.509 सर्टिफ़िकेट या एक वाक्य हो सकता है, और API अंदाज़ा लगाने से इंकार कर देता है कि वह कौन-सा है, इसलिए बाइट्स से टेक्स्ट की छलांग एक अलग, जान-बूझ कर लिया गया कदम है। तीसरी: वही कदम है जहाँ कैरेक्टर-सेट का फैसला होता है, और यहीं ज़्यादातर "मेरा Base64 कचरा बनकर वापस आया" वाले बग्स जन्मते हैं। हम थोड़ी ही देर में वहाँ पहुँचते हैं; पहले एक राउंड ट्रिप, यह साबित करने के लिए कि डिकोड ईमानदार है:

import kotlin.io.encoding.Base64
fun main() {
  val original = "Hello, World!".encodeToByteArray()
  val packed = Base64.encode(original)
  val back = Base64.decode(packed)
  println(packed)                    // SGVsbG8sIFdvcmxkIQ==
  println(back.contentEquals(original))  // true
}

चार स्कीम, चार मजाज़

यह क्लास कभी इंस्टैंशिएट नहीं होती; आप चार तैयार इंस्टेंस में से एक चुनते हैं, और हर एक अपना अलग मजाज़ लेकर डिकोड करता है:

import kotlin.io.encoding.Base64
fun main() {
  val data = "Hello?".encodeToByteArray()
  println(Base64.Default.encode(data))  // SGVsbG8/
  println(Base64.UrlSafe.encode(data))  // SGVsbG8_
  println(Base64.Mime.encode(data))     // SGVsbG8/
  println(Base64.Pem.encode(data))      // SGVsbG8/
}
इंस्टेंस वर्णमाला यह कैसे डिकोड करता है
Base64.Default A-Z a-z 0-9 + / सख़्त: वर्णमाला से बाहर का कोई भी चर थ्रो करता है; पैडिंग ज़रूरी है
Base64.UrlSafe A-Z a-z 0-9 - _ सख़्त, लेकिन URL वर्णमाला के ख़िलाफ़; इनपुट में + या / मिलने पर थ्रो करता है
Base64.Mime A-Z a-z 0-9 + / लचिला: लाइन सेपरेटर्स और बाकी गैर-वर्णमाला चरों को अनदेखा करता है, लेकिन = पैडिंग के आगे कुछ भी नहीं आ सकता; पैडिंग ज़रूरी है
Base64.Pem A-Z a-z 0-9 + / लचिला, Mime जैसे ही नियम; यह वही वर्णमाला है PEM/PKI फ़्लेवर में

लचिला/सख़्त का यह फ़र्क़ अंदर उतारने लायक सबसे उपयोगी बात है। Default और UrlSafe किसी भी बाहरी चर को घटनास्थल मानते हैं और तुरंत थ्रो कर देते हैं। Mime और Pem लाइन ब्रेक्स, स्पेसेस और बिखरे हुए पंक्तुचिह्नों को झेल लेते हैं - क्योंकि असली ईमेल और सर्टिफ़िकेट फ़ाइलों में बस वही मिलता है - फिर भी इनकी सीमाएँ हैं: जैसे ही पैडिंग के बाद किसी डेटा चर का चेहरा निकले, वे भी थ्रो कर देते हैं। सटीक एरर मैसेज आपको इसी लेख के आगे असफलता गाइड में दिखेंगे।

शख्सियतों का एक और नतीजा: एक स्कीम दूसरी स्कीम का आउटपुट पढ़ ही नहीं पाती। base64url टोकन Base64.Default को खिलाने पर - चर उसकी वर्णमाला में नहीं है, इसलिए आपको IllegalArgumentException: Invalid symbol '-'(55) at index ... मिलता है। अगर यह सवाल उठे कि स्ट्रिंग कहाँ से आई है, तो वह स्कीम चुनिए जो प्रोड्यूसर से मेल खाती है, जो आपके मूड से मेल खाती है, वही नहीं।

URL-Safe Base64 और JWTs

स्टैंडर्ड वर्णमाला के दो चर वही मुसीबत खड़ी करते हैं जैसे ही डेटा को URL के रास्ते सफ़र करना पड़ता है। क्वरी स्ट्रिंग में + को पढ़ने वाले तक पहुँचने से पहले आमतौर पर स्पेस की तरह दोबारा समझ लिया जाता है, और / पाथ सेपरेटर है, इसलिए वह URL सेगमेंट में बिल्कुल नहीं आ सकता। RFC 4648, सेक्शन 5, इसका हल वर्णमाला के अंतिम दो चिह्नों को बदलकर लाता है: + बनता है - और / बनता है _। जो नाम आप सबसे ज़्यादा सुनेंगे वह है base64url, और Kotlin में वह है Base64.UrlSafe।

base64url का सबसे बड़ा उपभोक्ता JSON Web Token है। compact शक्ल में JWT तीन base64url हिस्से हैं जो बिंदुओं से जुड़े होते हैं: header.payload.signature। RFC 7515 इन हिस्सों को base64url बिना पैडिंग के तय करता है, जो साधारण वर्णमाला से दूसरा फ़र्क़ है, बस चरों से नहीं। यहाँ एक टोकन का अनपैक होना, बस इंसपेक्शन के लिए:

import kotlin.io.encoding.Base64
fun main() {
  val token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
  val (header, payload, signature) = token.split(".")
  val lenient = Base64.UrlSafe.withPadding(Base64.PaddingOption.PRESENT_OPTIONAL)
  println(lenient.decode(header).decodeToString())
  // {"alg":"HS256"}
  println(lenient.decode(payload).decodeToString())
  // {"sub":"1234567890","name":"John Doe"}
  println(signature.length)  // 43
}

दो बातें नोट करने लायक हैं। टोकन के हिस्सों पर कोई पैडिंग नहीं होती, लेकिन Base64.UrlSafe बॉक्स से निकलते ही पैडिंग की माँग करता है, इसलिए withPadding(PRESENT_OPTIONAL) वाली पंक्ति असली काम कर रही है: वह पैडेड और बिना पैडिंग वाले दोनों इनपुट को स्वीकार करती है। और split(".") साथ में देस्ट्रक्चरिंग बस साधारण Kotlin है जो फ़ॉर्मैट की माँग के मुताबिक काम कर रहा है। एक गंभीर चेतावनी: JWT का अनपैक करना टोकन को देखने के लिए है, भरोसा करने के लिए नहीं। डिकोड के बाद हेडर और पेलोड साधारण डेटा ही हैं; सिर्फ़ वैरिफ़ाई हुई सिग्नेचर ही बताती है कि टोकन असली है, और उसके लिए आपको एक असली JWT लाइब्रेरी चाहिए, हाथ से बनी स्ट्रिंग स्प्लिटिंग नहीं।

पैडिंग मोड्स और सख़्ताई का डायल

Kotlin में Base64 के बारे में पैडिंग कोई ठोस तथ्य नहीं है; यह एक सेटिंग है। हर इंस्टेंस में एक PaddingOption रहता है, चारों प्रीसेट इंस्टेंस PRESENT से शुरू होते हैं, और withPadding आपको एक नया इंस्टेंस अलग सेटिंग के साथ सौंपता है जबकि मूल को छुए बिना छोड़ देता है। यहाँ वह डायल है, विकल्प-दर-विकल्प:

विकल्प इनपुट बिना पैडिंग इनपुट सही पैडिंग के साथ
PRESENT (हर जगह डिफ़ॉल्ट) थ्रो करता है डिकोड होता है
ABSENT डिकोड होता है थ्रो करता है
PRESENT_OPTIONAL डिकोड होता है डिकोड होता है
ABSENT_OPTIONAL डिकोड होता है डिकोड होता है
import kotlin.io.encoding.Base64
fun main() {
  val data = "Hello".encodeToByteArray()
  println(Base64.Default.withPadding(Base64.PaddingOption.ABSENT).encode(data))
  // SGVsbG8
  println(Base64.Default.encode(data))
  // SGVsbG8=
  val eitherWay = Base64.Default.withPadding(Base64.PaddingOption.PRESENT_OPTIONAL)
  println(eitherWay.decode("SGVsbG8").decodeToString())   // Hello
  println(eitherWay.decode("SGVsbG8=").decodeToString())  // Hello
}

डिकोडिंग की तरफ़, PRESENT_OPTIONAL आपकी सुरक्षा जाल है: यह वह विकल्प है जो कहता है "मुझे पता नहीं कि भेजने वाले ने पैडिंग लगाई या नहीं, और मैं काम जारी रखने वाला हूँ।" बाकी जोड़ो-मिलो के एरर मैसेज अनोखे तौर पर मददगार हैं, इसलिए जब सख़्त डिकोडर ग़लत इनपुट से मिले तो आप उन्हें तुरंत पहचान लेंगे: PRESENT के तहत पैडिंग न मिलने पर The padding option is set to PRESENT, but the input is not properly padded बनता है, और ABSENT के तहत पैडिंग मिलने पर The padding option is set to ABSENT, but the input has a pad character at index 7। एक व्यवहार को ख़ास नोट मिलने लायक है क्योंकि वह लोगों को चौंकाता है: SGVsbG8== जैसी डबल पैडिंग "ज़्यादा हो गया, पर चालू है" नहीं है। पहला = डेटा ख़त्म करता है, और दूसरा उस जगह बैठा है जहाँ डेटा की उम्मीद थी, इसलिए सबसे लचिले डिकोडर भी उसे ठुकरा देते हैं।

यहाँ एक वर्ज़न इतिहास भी छिपा है। अगर आपको ऐसा कोड मिला है जो एक्सपेरिमेंटल 1.8.x API के ख़िलाफ़ लिखा गया था, तो याद रखिए कि पुराना decode पैडिंग के साथ भी इनपुट लेता था और बिना पैडिंग के भी। Kotlin 2.0.20 में Default सख़्त PRESENT नियम पर आ गया, इसलिए वही बिना पैडिंग वाला इनपुट जो कभी काम करता था, उस पॉइंट रिलीज़ से आगे अपग्रेड करने पर अब थ्रो कर देता है। ठीक करने का तरीका एक लाइन का है: withPadding(Base64.PaddingOption.PRESENT_OPTIONAL), या डिकोड करने से पहले इनपुट्स को नॉरमलाइज़ कीजिए।

बाइट्स से टेक्स्ट तक: कैरेक्टर सेट और Unicode

जब आपके पास ByteArray हो जाता है, तो सवाल है कि उसका मतलब क्या है। अगर पेलोड टेक्स्ट है, तो डिफ़ॉल्ट जवाब है decodeToString(), जो बाइट्स को UTF-8 के रूप में समझता है और हर प्लेटफ़ॉर्म पर काम करता है। आधुनिक APIs, ईमेल और वेब डेटा के आम केस के लिए, यही बस आपको सारी ज़िंदगी काफ़ी रहेगा, इमोजी सहित:

import kotlin.io.encoding.Base64
fun main() {
  val original = "héllo 😀"
  val packed = Base64.encode(original.encodeToByteArray())
  println(packed)                                  // aMOpbGxvIPCfmIA=
  println(Base64.decode(packed).decodeToString())  // héllo 😀
}

लेकिन जैसे ही भेजने वाले ने UTF-8 के अलावा कुछ भी इस्तेमाल किया, कैरेक्टर सेट का फैसला आपके हाथ में है। Kotlin की बिल्ट-इन टेक्स्ट कन्वर्ज़न्स जान-बूझ कर सिर्फ़ UTF-8 ही हैं: decodeToString() में कोई कैरेक्टर सेट पैरामीटर नहीं है, और स्ट्रिंग-से-बाइट्स का कोई भी फ़ंक्शन जिसमें वह हो, वही नहीं है। JVM पर आप प्लेटफ़ॉर्म के कैरेक्टर सेट API पर उतर जाते हैं, जो ईमानदार और एक्सप्लिसिट है:

import kotlin.io.encoding.Base64
import java.nio.charset.Charset
fun main() {
  val latinOne = "héllo".toByteArray(Charsets.ISO_8859_1)
  val packed = Base64.encode(latinOne)
  println(packed)  // aOlsbG8=
  val asUtf8 = Base64.decode(packed).decodeToString()
  val asLatin = String(Base64.decode(packed), Charsets.ISO_8859_1)
  println(asUtf8)   // h?llo  (é वाला बाइट वैध UTF-8 नहीं है)
  println(asLatin)  // héllo
  val byName = String(Base64.decode(packed), Charset.forName("ISO-8859-1"))
  println(byName)   // héllo
}

बीच वाली लाइन में वह ? कोई फ़ॉन्ट की समस्या नहीं है; वह U+FFFD है, Unicode का रिप्लेसमेंट चर, जो किसी ऐसे बाइट की जगह खड़ा है जो वैध UTF-8 नहीं बना पा रहा। अगर डिकोड के बाद आपको उनका एक सिलसिला दिखे, तो आपका पेलोड ठीक है - आपका कैरेक्टर सेट का अंदाज़ा नहीं है। साथ में वह असममितता भी नोट कीजिए जो लोगों को काटती है: एन्कोडिंग की तरफ़ JVM एक्सटेंशन toByteArray(charset) मौजूद है; डिकोडिंग की तरफ़ मिलता-जुलता कॉन्स्ट्रक्टर है String(bytes, charset)। न ही किसी को कैरेक्टर सेट का नाम लेना है; उसके लिए आपको Charset.forName("...") चाहिए, जो बने-बनारे नाम पर UnsupportedCharsetException थ्रो करता है, ताकि कॉन्फ़िग वैल्यू में टाइपो चुपचाप किसी और एन्कोडिंग चुनने के बजाय जल्दी फेल हो जाए।

चूँकि हम बाइट-लैंड में ही हैं, एक Kotlin-खास फँसाव: Char एक 16-बिट वैल्यू है, और उस पर toByte() चुपचाप सिर्फ़ निचले आठ बिट्स ही रखता है। अगर आप चरों से हाथ से बाइट्स बना रहे हों, तो "中".first().code.toByte() आपको 45 देता है, एक ऐसा नंबर जो उस चर से किसी रिश्ते का नहीं है। सही रास्ता हमेशा encodeToByteArray() है, जो असली एन्कोडिंग का काम करता है - वही चर तीन UTF-8 बाइट्स है, और उसकी Base64 शक्ल है 5Lit। एन्कोडिंग स्टैंडर्ड लाइब्रेरी को करने दीजिए; कभी हाथ से चरों को बाइट्स में पैक न कीजिए।

फ़ाइलें, सबस्ट्रिंग्स और बड़े इनपुट

Base64 डेटा हमेशा मेमोरी में एक सुंदर स्ट्रिंग नहीं होता। कभी-कभी वह फ़ाइल होती है, किसी बड़े रिस्पॉन्स का एक स्लाइस, या इतनी बड़ी चीज़ कि एक साथ थामना ही मुश्किल हो। Kotlin आपको तीनों दरवाज़े देता है।

फ़ाइलें सबसे अच्छे अर्थ में बोरिंग केस हैं: बाइट्स पढ़ो, डिकोड करो, ख़त्म। दोनों स्टैंडर्ड फ़ाइल APIs काम करती हैं, जो भी आपका प्रोजेक्ट पहले से इस्तेमाल करता है:

import java.io.File
import kotlin.io.encoding.Base64
import kotlin.io.path.Path
import kotlin.io.path.readBytes
fun main() {
  val fromFile = File("payload.b64").readBytes()
  println(Base64.decode(fromFile.decodeToString()).size)  // डिकोडेड बाइट की गिनती
  val fromPath = Path("payload.b64").readBytes()
  println(Base64.decode(fromPath.decodeToString()).size)  // वही नंबर
}

सबस्ट्रिंग्स वही जगह है जहाँ CharSequence ओवरलोड्स अपनी रौनक दिखाते हैं। decode शुरुआत और अंत इंडेक्स के साथ कोई भी कैरेक्टर सिक्वेंस लेता है, इसलिए आप लंबे रिस्पॉन्स बॉडी का स्लाइस पहले उसका कॉपी बनाने के बिना सीधे उसे सौंप सकते हैं:

import kotlin.io.encoding.Base64
fun main() {
  val body = "prefix junk SGVsbG8= trailing junk"
  val bytes = Base64.decode(body, 12, 20)
  println(bytes.decodeToString())  // Hello
}

अगर आपको आउटपुट साइज़ पहले से पता है और आप बफ़र दोबारा इस्तेमाल करना चाहते हैं, तो decodeIntoByteArray आपके चुने हुए डिस्टिनेशन अरेय़ में लिखता है और बताता है कि उसने कितनी बाइट्स लिखीं। अगर बफ़र ज़्यादा छोटा दिया, तो वह IndexOutOfBoundsException थ्रो करता है जिसमें ज़रूरी कैपासिटी मैसेज के अंदर होती है, इसलिए एरर ख़ुद आपके साइज़िंग हिंट के काम आता है।

JVM पर सच में बड़े स्ट्रीम्स के लिए तीसरा दरवाज़ा है: स्ट्रीमिंग डिकोडर। वे अभी भी एक्सपेरिमेंटल चिह्नित हैं - इसीलिए ऑप्ट-इन एनोटेशन - और वे सिर्फ़ JVM के लिए मौजूद हैं, लेकिन वे सब कुछ मेमोरी में थामने के बजाय ऑन-द-फ़्लाई डिकोड करते हैं:

import java.io.ByteArrayInputStream
import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi
import kotlin.io.encoding.decodingWith
@OptIn(ExperimentalEncodingApi::class)
fun main() {
  val stream = ByteArrayInputStream("SGVsbG8gV29ybGQh".toByteArray())
  stream.decodingWith(Base64.Default).use {
    println(it.readBytes().decodeToString())  // Hello World!
  }
}

दो प्रैक्टिकल बारीकियाँ। एक्सटेंशन फ़ंक्शन पैकेज के टॉप लेवल पर रहते हैं, इसलिए आप उन्हें नाम से इम्पोर्ट करते हैं (स्टार इम्पोर्ट भी काम करता है, लेकिन नाम ज़्यादा मीठे हैं)। और डिकोडर पैडिंग को हार्ड स्टॉप मानता है: अगर Base64 सेक्शन के बाद नीचे का स्ट्रीम आगे बढ़ता रहे, तो डिकोडेड स्ट्रीम से पढ़ना = पर ख़त्म हो जाता है और बचे बाइट्स मूल स्ट्रीम में उपलब्ध ही रह जाते हैं। यह उन फ़ॉर्मैट्स के लिए साफ़-सुथरा है जो Base64 किसी और चीज़ के सामने चिपका देते हैं।

ट्रेंच में: HTTP APIs और JSON बॉडीज़

JSON रॉ बाइट्स नहीं उठा सकता - यह टेक्स्ट प्रोटोकॉल है - इसलिए APIs जो बायनेरी को सफ़र कराती हैं (इमेजेस, सर्टिफ़िकेट्स, कोई भी ब्लॉब) लगभग हमेशा उसे Base64 में पैक करके एक स्ट्रिंग फ़ील्ड के अंदर रैप करती हैं। पैटर्न है: JSON पार्स कीजिए, फ़ील्ड उठाइए, डिकोड कीजिए। ऑफिशियल serialization लाइब्रेरी के साथ JSON वाला हिस्सा बस दो एनोटेशन दूर है:

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlin.io.encoding.Base64
@Serializable
data class ImageResponse(val name: String, val data: String)
fun main() {
  val body = """{"name":"icon.png","data":"iVBORw0KGgo="}"""
  val response = Json.decodeFromString<ImageResponse>(body)
  val bytes = Base64.decode(response.data)
  println("${response.name}: ${bytes.size} bytes")  // icon.png: 8 bytes
}

इस उदाहरण को serialization प्लगइन और लाइब्रेरी चाहिए, जो बिल्ड में एक बार जोड़ी जाती हैं:

plugins {
  kotlin("jvm") version "2.4.10"
  kotlin("plugin.serialization") version "2.4.10"
}
dependencies {
  implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.11.0")
}

लाइब्रेरी के बिना वही विचार रॉ स्ट्रिंग पर भी काम करता है, जो तेज़ स्क्रिप्ट्स के लिए फ़ायदेमंद है: फ़ील्ड substringBetween से खींचिए और डिकोड कीजिए। फँसाव वे ही परिचित API वाले हैं: फ़ील्ड आख़िर में पूरा data URL भी हो सकती है (जिसमें data:image/png;base64, प्रीफिक्स हो, इसका इंतज़ाम इस लेख में बाद में होता है), पेलोड लाइन ब्रेक्स के साथ MIME-रैप्ड भी हो सकता है, और एन्कोडेड पेलोड मूल बायनेरी से करीब एक-तिहाई बड़ा भी हो सकता है, इसलिए बड़े रिस्पॉन्सेस पर अपना मेमोरी बजट देखते रहिए।

ट्रेंच में: ईमेल और MIME-रैप्ड इनपुट

ईमेल एक 7-बिट टेक्स्ट की दुनिया है, और RFC 2045 का बायनेरी अटैचमेंट्स के लिए जवाब है Base64, एक मोड़ के साथ: एन्कोडेड आउटपुट को रैप करना ज़रूरी है ताकि कोई भी लाइन 76 चरों से लंबी न बने। अगर आपको कभी अटैचमेंट टेक्स्ट की शक्ल में मिला है, तो वही वजह है कि वह Base64 की एक इंडेन्टेड कॉलम जैसा दिखता है। बस इसी इनपुट के लिए Base64.Mime सही डिकोडर है, क्योंकि वह चलते-चलते लाइन सेपरेटर्स और बाकी गैर-वर्णमाला चरों को अनदेखा कर देता है:

import kotlin.io.encoding.Base64
fun main() {
  val wrapped = "SGVs\nbG8=\r\n"
  println(Base64.Mime.decode(wrapped).decodeToString())  // Hello
  val withJunk = "Y@{mFz!Z!TY}0"
  println(Base64.Mime.decode(withJunk).decodeToString())  // base64
}

लचिलपन असली है, लेकिन सीमाओं वाला। इनपुट रैप कीजिए, एक-दो स्पेस छिड़क दीजिए, कोई बात नहीं। लेकिन आख़िरी = के आगे कोई डेटा चर जोड़ दीजिए, और Mime भी थ्रो कर देगा: Symbol 'e'(145) at index 7 is prohibited after the pad character। और याद रखिए कि Mime में भी पैडिंग मौजूद और सही होनी ज़रूरी है; एक MIME डिकोडर जो मिसिंग पैडिंग तक निगल ले, वह मुसीबत को निमंत्रण दे रहा होगा। गंदे इनकमिंग ईमेल पेलोड्स के लिए प्रैक्टिकल रेसिपी है: पहले Mime से डिकोड कीजिए, और अगर वह थ्रो करे, तो मैसेज को देखिए - वह बिल्कुल बताता है कि कौन-सा सिंबल, किस इंडेक्स पर, नियम तोड़ रहा था।

ट्रेंच में: इमेजेस और डेटा URLs

डेटा URL वेब का तरीका है किसी फ़ाइल को सीधे दस्तावेज़ के अंदर इनलाइन करने का: एक मीडिया टाइप, एक base64, मार्कर, और पेलोड, सब एक ही स्ट्रिंग में। ब्राउज़र, CSS और इम्बेडेड UI छोटे एसेट्स के लिए इन्हें प्यार करते हैं - आइकॉन्स, एवटार, प्लेसहोल्डर ग्राफ़िक्स - क्योंकि दूसरा रिक्वेस्ट करना ही नहीं पड़ता। फ़ॉर्मैट ऐसा दिखता है:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUg==

Kotlin में इसे डिकोड करना एक स्ट्रिंग ऑपरेशन है और उसके बाद Base64 डिकोड। प्रीफिक्स में कोई रहस्य नहीं छिपा; कॉमा के आगे की हर चीज़ पेलोड है:

import kotlin.io.encoding.Base64
fun main() {
  val dataUrl = "data:image/png;base64,iVBORw0KGgo="
  val mediaType = dataUrl.substringBefore(";")
  val packed = dataUrl.substringAfter("base64,")
  val bytes = Base64.decode(packed)
  println(mediaType)          // data:image/png
  println(bytes.size)         // 8
  println(bytes.contentToString())  // [-119, 80, 78, 71, ...]
}

वह पहला बाइट, -119 (जो 0x89 है), उसके बाद PNG के अक्षर - यह वही मैजिक नंबर है जो PNG फ़ाइल को पहचानता है। डिकोड के बाद पहले चार या आठ बाइट्स जाँचना एक सस्ता तरीका है यह कन्फ़र्म करने का कि डेटा URL में सच में वही है जो उसका प्रीफिक्स दावा करता है। दो ईमानदार चेतावनियाँ: Base64 साइज़ में करीब एक-तिहाई जोड़ता है, इसलिए डेटा URL वह साइज़-बदलाव है जो आप नेटवर्क राउंड ट्रिप के ख़िलाफ़ करते हैं, और बड़ी किसी भी चीज़ के लिए आमतौर पर बेहतर यह होता है कि फ़ाइल असली URL से सर्व की जाए और कैश को अपना काम करने दी जाए।

ट्रेंच में: कॉन्फ़िग, एनवायरनमेंट वेरिएबल्स और डेटाबेस

Base64 कॉन्फ़िग फ़ाइलों और एनवायरनमेंट वेरिएबल्स में तब-तब दिखता है जब किसी बायनेरी वैल्यू को टेक्स्ट-ओन्ली चैनल में सफ़र करना पड़े: properties फ़ाइल में छोटा इम्बेडेड आइकॉन, कंटेनर पर किसी env var में संचित टोकन, या टेक्स्ट कॉलम में पार्क किया हुआ बाइट ब्लॉब इसलिए क्योंकि स्कीमा सही बायनेरी टाइप से पहले की है। डिकोड की तरफ़ हर जगह वही दो कदम हैं - टेक्स्ट पढ़िए, डिकोड कीजिए:

import kotlin.io.encoding.Base64
fun main() {
  val line = "icon: UE5HREFUQQ=="
  val packed = line.substringAfter("icon: ").trim()
  val bytes = Base64.decode(packed)
  println(bytes.decodeToString())  // PNGDATA
  val fromEnv: String? = System.getenv("MY_ICON_B64")
  if (fromEnv != null) {
    println(Base64.decode(fromEnv).size)
  }
}

पूरे इलाक़े का फँसाव एक लाइन में समा जाता है: Base64 एनक्रिप्शन नहीं है। यह ट्रांसपोर्ट ट्रिक है, लॉक नहीं। किसी को भी Base64 वैल्यू पढ़कर लगना चाहिए नहीं कि अंदर का डेटा छिपा है; वह बस एक फ़ंक्शन कॉल दूर दृश्य होने से है, और वह हर लॉग लाइन में दृश्य है जो आप लिखते हैं। अगर कोई वैल्यू संवेदनशील है, तो उसे सिरे से सिरे तक संवेदनशील रखिए - secret store, एन्क्रिप्टेड कॉलम, आपका स्टैक जो भी देता है - और Base64 का इस्तेमाल सिर्फ़ बाइट्स को टेक्स्ट के रास्ते सफ़र कराने के लिए कीजिए, उनकी रक्षा करने के लिए नहीं।

ट्रेंच में: कमांड लाइन

सबसे पुराना use case: कमांड लाइन पर बेठका Base64 ब्लॉब को फ़ाइल में बदलना। पूरा टूल आठ लाइनों का Kotlin है, क्योंकि भारी काम स्टैंडर्ड लाइब्रेरी करती है। इसे Kotlin कंपाइलर से एक बार कंपाइल कीजिए और यह हमेशा के लिए आपका है:

import java.io.File
import kotlin.io.encoding.Base64
fun main(args: Array<String>) {
  val packed = if (args.isNotEmpty()) args[0] else readlnOrNull().orEmpty()
  val bytes = Base64.decode(packed.trim())
  File("decoded.bin").writeBytes(bytes)
  println("Wrote ${bytes.size} bytes to decoded.bin")
}

एक-बार की वैल्यू के लिए इसे एरगुमेंट के साथ चलाइए, या बैच काम के लिए फ़ाइल उसमें पाइप कीजिए: प्रोग्राम पहला एरगुमेंट पढ़ता है अगर वह मौजूद हो, वरना standard input पर गिर जाता है। trim() यहाँ चुपचाप अपना काम कर रहा है, क्योंकि शेल एरगुमेंट्स और पेस्ट की गई वैल्यूज़ बिखरे हुए व्हाइटस्पेस के साथ आना पसंद करती हैं जिसे सख़्त डिकोडर ठुकरा देगा। और अगर आपके पेलोड base64url हैं, तो Base64.decode की जगह Base64.UrlSafe.withPadding(Base64.PaddingOption.PRESENT_OPTIONAL).decode रख दीजिए और टूल टोकन के लिए भी तैयार है।

डिकोडिंग असफलताओं की फ़ील्ड गाइड

इस गाइड के हर डिकोडर एक में से दो एक्ससेप्शन टाइप्स से फेल होते हैं, और हर मैसेज इतना स्पेसिफिक है कि वह बिल्कुल बताता है क्या ग़लत हुआ। यहाँ पूरा नक्शा है, स्टैंडर्ड लाइब्रेरी द्वारा पैदा किए गए सटीक मैसेजों के साथ:

हाल एक्ससेप्शन मैसेज (जैसा बनता है)
वर्णमाला से बाहर का चर (स्पेस, नई लाइन, ग़लत स्कीम का सिंबल) IllegalArgumentException Invalid symbol ' '(40) at index 5
पैडिंग के बाद डेटा चर IllegalArgumentException Symbol 'e'(145) at index 7 is prohibited after the pad character
विकल्प PRESENT होने पर पैडिंग का न मिलना IllegalArgumentException The padding option is set to PRESENT, but the input is not properly padded
विकल्प ABSENT होने पर पैडिंग का होना IllegalArgumentException The padding option is set to ABSENT, but the input has a pad character at index 7
सोर्स की सीमा से बाहर का इंडेक्स IndexOutOfBoundsException startIndex: 0, endIndex: 100, size: 8
startIndex जो endIndex से बड़ा हो IllegalArgumentException startIndex: 3 > endIndex: 2
decodeIntoByteArray के लिए डिस्टिनेशन बफ़र बहुत छोटा IndexOutOfBoundsException The destination array does not have enough capacity, destination offset: 0, destination size: 2, capacity needed: 8

पहली दो पंक्तियों में पैटर्न नोट कीजिए: मैसेज दोषी सिंबल का नाम, कोष्ठक में उसका न्यूमेरिक कोड, और उसका इंडेक्स बताता है। यह डीबगिंग का तोहफ़ा है। जब प्रोडक्शन में कोई डिकोड थ्रो करे, तो इनपुट के पहले कुछ दर्जन चर और मैसेज का इंडेक्स लॉग कीजिए, और लगभग हमेशा आप कुछ सेकंड में दोषी तक पहुँच जाते हैं - चाहे वह पेस्ट किया हुआ नई लाइन हो, काटा हुआ पेलोड, या base64url स्ट्रिंग जो standard डिकोडर में भटक आई हो।

वह फँसाव जो ख़ास तौर पर Kotlin डेवलपर्स को चोट पहुँचाते हैं

  • पेलोड को टेक्स्ट मान लेना। decode जान-बूझ कर ByteArray लौटता है। किसी JPEG पर "शायद टेक्स्ट है" सोचकर decodeToString() कॉल करने से आपको रिप्लेसमेंट चरों की एक दीवार मिलती है। कन्वर्ट करने से पहले तय कीजिए कि वे बाइट्स क्या हैं।
  • कॉपी-पेस्ट व्हाइटस्पेस। डिफ़ॉल्ट डिकोडर सख़्त है, और चैट मैसेज या लॉग से उठाई गई वैल्यू लगभग हमेशा ट्रेलिंग नई लाइन या लीडिंग स्पेस के साथ आती है। डिकोड से पहले trim कीजिए, या Mime के रास्ते डिकोड कीजिए, या IllegalArgumentException को स्वीकार करके हैंडल कीजिए।
  • एक्सपेरिमेंटल युग से अपग्रेड। 1.8.x एक्सपेरिमेंटल API के लिए लिखा कोड @OptIn(ExperimentalEncodingApi::class) एनोटेशन के साथ चलता था और इस भरोसे पर था कि पैडिंग वैकल्पिक है। 2.0.20 से, वही इनपुट थ्रो कर सकता है। ठीक करने का तरीका PRESENT_OPTIONAL है, या इनपुट्स को डिकोडर तक पहुँचने से पहले साफ़ कर लेना है।
  • स्कीम को ग़लत प्रोड्यूसर से मेल देना। JWT का हिस्सा जो Base64.Default से डिकोड हो, अपने - और _ चरों पर फेल हो जाता है; स्टैंडर्ड वर्णमाला का पेलोड जो UrlSafe से डिकोड हो, + और / पर फेल हो जाता है। एक्ससेप्शन सटीक सिंबल का नाम बताता है, लेकिन ठीक करने का रास्ता यह जानना है कि स्ट्रिंग कहाँ से आई।
  • कैरेक्टर सेट की खाई। decodeToString() सिर्फ़ UTF-8 है, बाकी एन्कोडिंग्स का कोई ओवरलोड नहीं। अगर भेजने वाले ने Latin-1 या Windows-1252 इस्तेमाल किया, तो JVM पर String(bytes, charset) की योजना बनाइए, और याद न रहने पर लक्षण U+FFFD रिप्लेसमेंट चर ही हैं।
  • डिस्ट्रीब्यूशन पैकेज का कंपाइलर। Debian और Ubuntu पर apt install kotlin 1.3.31 देता है, जो इस API के मौजूद होने से पहले की है। अगर आपके उदाहरण अचानक "unresolved reference" के साथ कंपाइल करने से मना करने लगे, तो जाँचिए कि PATH पर असल में कौन-सा कंपाइलर है।

डिकोडिंग के लिए बेस्ट प्रैक्टिस

  • पहले बाइट्स में डिकोड कीजिए, समझना दूसरे नंबर पर। Base64.decode और टेक्स्ट कन्वर्ज़न को अलग-अलग कदमों के रूप में रखिए। इससे कैरेक्टर सेट एक्सप्लिसिट हो जाता है, बायनेरी पेलोड बायनेरी बने रहते हैं, और टेस्ट तुरंत हो जाते हैं: बाइट अरेय़ की तुलना कीजिए, स्ट्रिंग्स की नहीं।
  • वह इंस्टेंस चुनिए जो प्रोड्यूसर से मेल खाता है। JWT और URL-बाँधे डेटा का मतलब है UrlSafe; ईमेल और PEM फ़ाइलों का मतलब है Mime या Pem; बाकी सब Default से शुरू होता है। लचिले डिकोडर ज्ञात-गंदे इनपुट के लिए हैं, कोई जनरल सुरक्षा जाल नहीं।
  • अनट्रस्टेड इनपुट को एक बार, ज़्यादा ख़र्च किए बिना, नॉरमलाइज़ कीजिए। सख़्त डिकोड से पहले trim(), और जहाँ फ़ॉर्मैट साफ़ होने के लिए ज्ञात हो वहाँ व्हाइटस्पेस स्ट्रिप, try-catch की किसी भी मात्रा से ज़्यादा असली दुनिया की असफलताएँ पकड़ता है। अज्ञात सोर्स की वैल्यूज़ के लिए PRESENT_OPTIONAL फ़ॉलबैक वाला छोटा हेल्पर एक अच्छा पैटर्न है।
  • अलोकेशन से पहले साइज़ का बजट बनाइए। डिकोडेड आउटपुट इनपुट लंबाई का ज़्यादा से ज़्यादा तीन-चौथाई होता है (चार सिंबल तीन बाइट्स उठाते हैं), इसलिए एक तेज़ लंबाई जाँच डिकोड से पहले ही डिस्टिनेशन साइज़ बता देती है, और यही बिल्कुल वह है जो आप pre-अलोकेटेड बफ़र भरने या मल्टी-मेगाबाइट स्ट्रिंग स्वीकार करने से पहले जानना चाहते हैं।
  • एरर मैसेज पर भरोसा कीजिए। स्टैंडर्ड लाइब्रेरी सिंबल, उसका कोड और उसका इंडेक्स रिपोर्ट करती है। अनट्रस्टेड इनपुट के लिए उस इंडेक्स के इलाक़े को लॉग कीजिए और अंदाज़े लगाना बंद कीजिए।
  • चीज़ें छुपाने के लिए डिकोड न कीजिए, और चीज़ें साबित करने के लिए डिकोड न कीजिए। Base64 एक ट्रांसपोर्ट एन्कोडिंग है। यह न गोपनीयता जोड़ती है न अखंडता; अगर आपको इनमें से कोई चाहिए, वह क्रिप्टोग्राफी का काम है, डिकोडर का नहीं।

Base64 Kotlin में कैसे आया

Base64 Kotlin से कुछ दशकों पुराना है - 76-चरों की लाइन नियम देने वाली MIME स्पेसिफिकेशन 1993 की है, और वर्णमाला ख़ुद मध्य-1990s के RFCs की - लेकिन Kotlin-खास कहानी छोटी और हाल की है। kotlin.io.encoding पैकेज अप्रैल 2023 में Kotlin 1.8.20 में आया, साथ में Base64 और तीन इंस्टेंस - Default, UrlSafe और Mime - @ExperimentalEncodingApi एनोटेशन के पीछे, और साथ में JVM-only स्ट्रीमिंग एक्सटेंशन जो आज भी एक्सपेरिमेंटल हैं। दो साल तक उसे इस्तेमाल करने का मतलब था हर फ़ंक्शन में एक ऑप्ट-इन लाइन, और API के हिलने की थोड़ी सी संभावना।

Kotlin 2.2.0, जो जून 2025 में रिलीज़ हुआ, अनुबंध बदल दिया। पूरा API एक ही रिलीज़ में स्टेबल हो गया, और Pem इंस्टेंस परिवार में शामिल हो गया (PKI के चारों ओर इस्तेमाल होने वाला RFC 1421, 64-चरों की लाइन वाला वेरिएंट)। वह सख़्ताई जो 1.8 युग की पैडिंग-वैकल्पिक कोड को अपग्रेड के बाद ध्यान माँगने लगाती है, एक कदम पहले आई थी: 2.0.20 में, जब withPadding अपने चार PaddingOption वैल्यूज़ के साथ पुराने फिक्स्ड व्यवहार की जगह ले बैठा और डिकोडर ने पैडिंग माँगना शुरू किया। 2.2 रिलीज़ ने साथ में kotlin.text के बंधु HexFormat क्लास को भी स्टेबलाइज़ किया, वह hex फ़ॉर्मैटिंग API जो Kotlin 1.9 से एक्सपेरिमेंटल थी, ताकि बाइट-लेवल टेक्स्टुअल एन्कोडिंग्स का अब स्टैंडर्ड लाइब्रेरी में एक बसा हुआ घर है। और रख-रखाव की नोट: Kotlin 2.4.0 से JVM स्टैंडर्ड लाइब्रेरी हर रिलीज़ लाइन के साथ 18-महीने के सपोर्ट विंडो के साथ आती है, जो एक और वजह है कि वर्तमान 2.4.x लाइन पर कोई प्रोजेक्ट इस API को चलती-फिरती चीज़ की बजाय एक स्थिर बिंदु मान सके।

मज़ेदार तथ्य

  • कॉम्पैनिऑन ऑब्जेक्ट काम करता है। चूँकि Default Base64 का कॉम्पैनिऑन है, क्लास का नाम डिफ़ॉल्ट इंस्टेंस के रूप में भी काम आता है: Base64.decode(x) और Base64.Default.decode(x) एक ही कॉल हैं। इसीलिए इस लेख के ऊपर वाला दो-लाइन का उदाहरण दो लाइनों पर ही रहता है।
  • स्ट्रिंग डिकोडिंग को JVM पर स्पीड हैक मिलता है। आम डिकोडिंग लूप बाइट्स पर काम करता है, लेकिन Kotlin की स्ट्रिंग्स कैरेक्टर सिक्वेंस हैं। JVM इम्प्लीमेंटेशन कन्वर्ज़न को टालता है: शेयर्ड लूप चलने से पहले String के कैरेक्टर को सिंगल-बाइट ISO-8859-1 वैल्यू के रूप में दोबारा पढ़ लेता है - सोर्स कोड के कॉमेंट का दावा है कि यह आम रास्ते से दस गुना तक तेज़ है, और इसीलिए decode(String) लंबे पेलोड पर भी तुरंत लगता है।
  • पैकेज का नाम संकेत है। आप यह API kotlin.io.encoding में पाएँगे, kotlin.text में नहीं, क्योंकि पूरा मक़सद यह है कि डेटा बाइट्स हैं - इनपुट और आउटपुट I/O की शक्ल के हैं, और टेक्स्ट बस उसके बाद रिज़ल्ट के साथ जो होता है।
  • एरर मैसेज में कैरेक्टर का कोड शामिल है। Symbol 'e'(145) दोषी सिंबल का वैल्यू ऑक्टल में रिपोर्ट करता है, बस उसका ग्लिफ़ नहीं। जब दोषी व्हाइटस्पेस हो तो फ़ायदेमंद: ' '(40) आपको इससे आप शक करने से बहुत पहले बता देता है कि वह स्पेस था।
  • PEM देर से आया। Base64.Pem मूल 1.8.20 API का हिस्सा नहीं था; यह 2.2 स्टेबलाइज़ेशन के साथ दिखा। अगर 2023 या 2024 का कोई ब्लॉग पोस्ट सिर्फ़ तीन इंस्टेंस गिनाता है, तो वह ग़लत नहीं है - बस दो रिलीज़ पुराना हो गया है।
  • यह हर प्लेटफ़ॉर्म के लिए अलग लिखा गया है, डिलीगेट नहीं। स्टैंडर्ड लाइब्रेरी expect/actual फ़ंक्शन के साथ हर टारगेट के लिए कोडेक अलग-अलग इम्प्लीमेंट करती है। JVM पर एक कॉमेंट-आउट ऑप्टिमाइज़ेशन भी है जो काम java.util.Base64 को सौंप देता, जो एक खुले कंपाइलर इश्यू के पीछे बंद है, और इसीलिए हर प्लेटफ़ॉर्म पर Kotlin इम्प्लीमेंटेशन का व्यवहार ही रेफ़रेंस व्यवहार है।

निष्कर्ष

Kotlin में Base64 डिकोड करना कुछ चुनिंदा, जान-बूझ कर की गई तयारियों की छोटी सूची है: वह इंस्टेंस जो उस सोर्स से मेल खाता है जहाँ डेटा आया, वह पैडिंग मोड जो उस भेजने के तरीके से मेल खाता है, वह बफ़र या स्ट्रीम जो उसका आकार तय करती है, और वह कैरेक्टर सेट जो उसका मतलब तय करता है। स्टैंडर्ड लाइब्रेरी चारों को साधारण फ़ंक्शन के रूप में, बिना किसी डिपेंडेंसी के, सौंपती है, और उसके एरर मैसेज इतने स्पेसिफिक हैं कि एक असफलता रहस्य नहीं, डायग्नोसिस बन जाती है। उल्टी दिशा - जब Base64 बनाने वाले आप हैं, तो सही स्कीम, पैडिंग और लाइन रैपिंग चुनना - अपने फैसले और अपने फँसाव रखती है, और बहन साइट का संबंधित लेख Kotlin में Base64 एन्कोडिंग को गहराई से कवर करता है।

अंतिम अपडेट: 2026-09-08

संबंधित लेख: Kotlin में Base64 एन्कोडिंग: एक सम्पूर्ण गाइड